代码之家  ›  专栏  ›  技术社区  ›  Jaime Montoya

为什么PHP fopen()函数不能使用755和775文件夹权限?

  •  0
  • Jaime Montoya  · 技术社区  · 5 年前

    我用的是ACRA( https://github.com/ACRA/acra )用于自动将我的Android崩溃报告发布到报告服务器。我有一个PHP脚本,它使用以下几行代码将日志文件写入 https://example.com/logs/ 我的测试服务器上的文件夹:

    $FileLog = $_SERVER['DOCUMENT_ROOT'] . "/logs/" . $fname;
    $HandleLog = fopen($FileLog, 'a');
    

    PHP fopen() 只有当 logs/ “我的服务器”上的文件夹具有以下权限:

    drwxrwxrwx (777)
    

    我已经试过了 drwxrwxr-x (775) drwxr-xr-x (755) 还有 fopen() 功能不起作用。只有当我使用 drwxrwxrwx (777) 对于 日志/ 文件夹权限。

    这对我来说很奇怪,因为我正在运行的PHP脚本在我的服务器上,所以当我执行 fopen($FileLog, 'a') 从我服务器上的PHP文件来看,如果 https://example.com/logs/ 是一个包含 drwxrwxr-x(775) 权限,因为使用 fopen($FileLog,'a') 也在同一条线上 https://example.com 服务器关于为什么只有777个权限有效,你有什么提示吗?我知道 DRWXRWX(777) 网络服务器的权限是不允许的。谢谢。

    更新1:

    使用 fopen($FileLog,'a') 是在 https://example.com/loggingscript.php 它由ACRA库调用( https://github.com/ACRA/acra )当我的Android应用程序崩溃时。

    1 回复  |  直到 5 年前
        1
  •  1
  •   symcbean    5 年前

    虽然Barmar通常会在这里给出很好的建议,但在这种情况下,我不同意“目录应该由运行Web服务器的用户拥有”。

    八进制权限中的每个数字,以及权限字符串中的每个“rwx”都与用户、组和任何其他uid(其中用户和组是文件上的属性)相关联。如果您的PHP脚本应该写入日志,那么它需要作为任何用户、组或其他人执行和写入目录的权限。虽然通常情况下,Web服务器uid应该是专用Web服务器主机上权限最低的帐户(因此通过“其他”授予访问权限),但情况并非总是如此。例如,如果主机上还有电子邮件MTA,那么更好的解决方案可能是770,通过组所有权授予Web服务器访问权限。将webserver uid设置为目录的所有者应该始终是一个自动的红色标志。

    您设置的权限模型应该反映对文件的所有访问,从而启用 全部的 访问文件的相关方(web开发人员、备份软件、日志轮换服务帐户…)它还应该限制任何没有明确打算访问的人的访问。OP没有告诉我们与该目录相关联的用户/组/该目录是否可更改/谁需要什么访问权限)。

    我知道DRWXRWX(777)对web服务器的权限是否定的

    不一定——这应该 从不 可以是默认设置,但有时它是Web服务器uid可写内容的正确配置。人们对此感到兴奋的原因是,权限有问题的人通常认为这是一个快速解决方案,他们不应该向PHP提供对内容的写访问权限。

    还有一个 大量的 此处暴露的安全漏洞(未提及其他缓解措施)。限制PHP可以写的地方的主要原因是防止最终用户注入代码。为了进行攻击,攻击者还必须能够调用他们在服务器上放置的代码。通常,日志包含用户提供的数据——因此允许PHP写入数据可以启动攻击的第一阶段。如果数据写在文档根目录中,那么它可以通过浏览器的URL直接寻址。

    OP将权限更改为755并没有减轻这种攻击,并且造成了只有PHP代码和root用户才能在创建日志文件后删除它们的情况。

        2
  •  0
  •   Barmar    5 年前

    该目录应为运行Web服务器的用户所有。否则,它需要world write权限,以便其他用户可以对其进行写入。

    这可能是 www-data apache .如果你不确定这是什么,请参见

    Finding out what user Apache is running as?

        3
  •  0
  •   Jaime Montoya    5 年前

    巴尔马的回答是解决方案。但为了准确记录我所做的事情,我在下面写下了详细的步骤。

    跑步 # ps aux | egrep '(apache|httpd)' 显示运行web服务器的用户 www-data :

    # ps aux | egrep '(apache|httpd)'
    www-data  3735  0.0  2.6 273160 12996 ?        S    06:25   0:00 /usr/sbin/apache2 -k start
    www-data  3736  0.0  2.6 273148 12892 ?        S    06:25   0:00 /usr/sbin/apache2 -k start
    www-data  3738  0.0  2.6 273216 13092 ?        S    06:25   0:00 /usr/sbin/apache2 -k start
    www-data  7163  0.0  2.6 273180 12888 ?        S    12:56   0:00 /usr/sbin/apache2 -k start
    www-data  7165  0.0  2.6 273176 13000 ?        S    12:56   0:00 /usr/sbin/apache2 -k start
    www-data  8209  0.0  2.6 273200 13032 ?        S    14:26   0:00 /usr/sbin/apache2 -k start
    www-data  8211  0.0  2.6 273128 12904 ?        S    14:26   0:00 /usr/sbin/apache2 -k start
    www-data  8219  0.0  2.6 273128 12896 ?        S    14:26   0:00 /usr/sbin/apache2 -k start
    www-data  8221  0.0  3.3 273192 16412 ?        S    14:26   0:00 /usr/sbin/apache2 -k start
    www-data  8235  0.0  2.6 273196 13008 ?        S    14:26   0:00 /usr/sbin/apache2 -k start
    root     12976  0.0  0.2  13136  1048 pts/0    S+   22:09   0:00 grep -E --color=auto (apache|httpd)
    root     29850  0.0  4.7 268240 23488 ?        Ss   Aug07   0:10 /usr/sbin/apache2 -k start
    

    我把那个文件夹的所有权从 root www数据 :

    # chown www-data logs/
    # chgrp www-data logs/
    

    现在一切正常,而我 755 作为我的 logs 文件夹。