我正在尝试使用realpath()来避免目录遍历攻击,而我无法弄清楚为什么它会在肯定存在的文件上返回false。
这些文件托管在Apache用户可以访问的NFS共享上。整个层次结构是755,除了文件本身是777。
以下是代码段:
$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"
之前有人遇到过这种行为吗?
答案 0 :(得分:1)
我想我自己想出了这个!好的'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
为我修好了。
答案 1 :(得分:0)
不要采取以下措施:这个答案是根据访问权限的详细组合的错误记录编写的:755已经允许所有人执行!
你说:
整个层次结构是755,除了文件本身是777。
虽然PHP manual page说:
正在运行的脚本必须对层次结构中所有目录具有可执行权限,否则realpath()将返回FALSE。
因此,您要将整个层次结构设置为777到此realpath()
才能生效。