【问题标题】:Protecting from LFI-like vulnerabilities when the file doesn't exist yet在文件尚不存在时防止类似 LFI 的漏洞
【发布时间】: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][-_] 应该是您允许的全部,并提供扩展名。让您的工作轻松很多。

标签: php security web realpath


【解决方案1】:

如何检查realpath(dirname($file))是否在根目录下?

$dir = $path;
$found = false;

while ($dir) {
    $dir = dirname($dir);
    if (!is_dir($dir)) {
        continue;
    }

    if (strpos(realpath($dir), $root) === 0) {
        $found = true;
    }

    break;
}

var_dump($found);

【讨论】:

  • 顺便说一句:你的检查方法只有在 $path == $root 时才返回 true,所以我猜这不是很正确
猜你喜欢
  • 2021-01-13
  • 1970-01-01
  • 2021-10-21
  • 2012-06-08
  • 2013-02-16
  • 1970-01-01
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多