PHP-realpath不工作;文件肯定存在


PHP - realpath not working; file definitely exists

我正试图使用realpath()来避免目录遍历攻击,但我不太明白为什么它在一个肯定存在的文件上返回false。

这些文件托管在Apache用户可以访问的NFS共享上。除了文件本身为777之外,整个层次结构为755。

下面是一个代码片段:

$path = "/mnt/share/path/to/20160111-133552-msg0000.wav";
$path = realpath($path);
var_dump($path);

结果是:

bool(false)

文件肯定在那里。我登录到Apache用户并运行:

bash-4.2$ ls -lah /mnt/share/path/to/20160111-133552-msg0000.wav
-rwxrwxrwx. 1 1001 1001 77K Jan 11 13:35 /mnt/share/path/to/3000-20160111-133552-msg0000.wav

另一个观察结果是:当我从$path变量中删除文件名时:

$path = "/mnt/share/path/to/

它运行得很好:

string(39) "/mnt/share/path/to"

以前有人遇到过这种行为吗?

我想这是我自己想出来的!Good ol’selinux阻止httpd访问文件:

type=AVC msg=audit(1452550767.071:18495): avc:  denied  { read } for  pid=10397 comm="httpd" name="3000-20160111-133552-msg0000.wav" dev="0:41" ino=12483 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:nfs_t:s0 tclass=file
    Was caused by:
    One of the following booleans was set incorrectly.
    Description:
    Allow httpd to use nfs
    Allow access by executing:
    # setsebool -P httpd_use_nfs 1

我是在尝试对有问题的.wav文件执行readfile()操作时才发现这一点的,但遇到了拒绝权限的错误,这在777文件上没有意义。检查了/var/log/audit/audit.log,这是显而易见的。

运行setsebool -P httpd_use_nfs 1为我修复了它。

不要认为以下是真的:这个答案是基于对访问权限的详细组合的记错而写的:755已经允许所有人执行了


你说:

除了文件本身是777之外,整个层次结构是755。

而PHP手册页面上写着:

运行的脚本必须对层次结构中的所有目录具有可执行权限,否则realpath()将返回FALSE。

因此,您需要将整个层次结构设置为777,以使realpath()工作。