【发布时间】:2012-07-25 17:32:56
【问题描述】:
如果用户在服务上请求文件,我通常可以通过使用 PHP 的 realpath() 并确保它位于根目录下来防止他们访问超出我想要的范围的文档。比如这样:
$path = realpath($_GET['path']);
// Protect against LFI vulnerabilities
if (substr($path, 0, strlen($root)) == $root)
{
// safe
}
但是,realpath() 仅适用于已经存在的文件。 如果我想确保用户将要写入我的脚本的位置在根目录下怎么办?
我不能使用 realpath(),我应该检查并去掉“..”引用吗? 还是有更好的办法?
【问题讨论】:
-
您可以
basename路径,并检查它是否在您的根目录中。我假设您的用户将写入现有的上传目录,或者类似的东西——如果不是,那显然是行不通的。 -
如果应用程序尝试写入不存在的目录,则会引发错误,因此可以安全地假设该目录存在。我知道
basename,但不知道这会有什么帮助。你能给出一个代码示例吗? -
哎呀,我的意思是目录名:
if (substr(dirname($path, 0, strlen($root)) == $root)。 -
来自文档:“dirname() 天真地对输入字符串进行操作,并且不知道实际的文件系统或路径组件,例如 '..'”,我也尝试过并验证了它不解析像'..'这样的组件
-
如果用户控制文件所在的目录,那么您可以从输入中删除任何“../”字符,然后使用它。如果您控制他们上传到哪个目录,只需检查有效的文件名 - [a-z][A-Z][-_] 应该是您允许的全部,并提供扩展名。让您的工作轻松很多。