【问题标题】:how to safely join strings to a path in php? [duplicate]如何安全地将字符串连接到 php 中的路径? [复制]
【发布时间】:2014-01-06 15:06:52
【问题描述】:

我有一个字符串的恒定开头和一个可变结尾,我如何保护字符串,以免在我注入的字符串包含的情况下创建后退(或升压)

../

这是一个简短的示例代码:

$dir = 'my/base/path/';
$file = $dir . $userSelectedFilename;
unlink($file);

如果$userSelectedFilename'../../myFileName',我认为这会导致我的脚本实际上尝试取消链接my/myFilename 上两个目录级别的内容,这显然不是我想要允许的,我想将其保留在基本路径下my/base/path/ 在所有情况下。

【问题讨论】:

  • my/base/path/../../myFileName - 我可能很厚,但至少在我的服务器上不会上升,只会导致错误!
  • 使用 realpath 函数来消除符号链接,例如 Gumbo 的建议中出现的 .../// 等。

标签: php string security code-injection


【解决方案1】:

我建议以下,并且只有以下方法:

<?
$dir = 'my/base/path/';
$file = $dir . $userSelectedFilename;
if(strpos(realpath($file),realpath($dir)) === 0) && is_file($file)) { // beware of the three ===
  unlink($file);
}

为什么?

依靠 realpath 找出文件的真实位置是安全的,这消除了目录遍历/多字节双点等。

然后我们检查文件的重新路径的开头是否真的是我们expacted目录(strpos)的开头。

之后我们还会检查该文件是否真的是一个文件,而不是一些指向其他地方的符号链接或类似的东西。

我看到字符消除解决方案被多字节字符串和类似攻击破坏。

到目前为止,这种方法可以承受所有这些。

【讨论】:

  • 我明白你的意思。如果我在我的 $userSelectedFilename 中禁止所有点一起使用,那会保护我吗?还是斜杠单独会产生目录遍历?
  • 您不再需要检查点,上面的解决方案可以解决这个问题。用户可以指定 folder1/folder1/../ 并将在文件夹 1 中。只要用户留在指定的目录中就可以了。
  • 是的,但是如果我只允许以安全字符串开头,我只需要在一个地方做(我很懒)=)那么 no-dots-policy 能保证我的安全吗?跨度>
  • 如果您的字符串被音译为 ascii 并且不包含双点,并且目标实际上是一个文件,而不是符号链接或目录以及该树中的所有目录,那么是的 - 您可能是。跨度>
【解决方案2】:

您可以通过以下方式过滤掉这些字符:

$file = preg_match("/\.\.\//", "", $file)

这将删除字符串../的出现

顺便说一句,您可能应该找到一种不同的方式来允许用户选择要删除的文件,而不是允许他们将路径作为字符串输入,可能是通过向他们显示可以删除的文件的目录列表或其他方式像这样。

【讨论】:

  • 谢谢,我会用正则表达式。至于您的旁注-这是一个很好的建议,但这不是我正在做的事情,我只是简化了我的案例以专注于问题。非常感谢!
  • true,它过滤路径。但它并没有真正检查文件是否在目录中。我知道这不是答案的一部分,但必须牢记。目录中指向外部的符号链接呢?
【解决方案3】:

你可以这样做“my/base/path/../../dir/”,如果你想要“真实”的路径使用这个:

 echo realpath($dir."../../dir/"); // my/dir

http://php.net/manual/en/function.realpath.php

【讨论】:

  • true,但在这种情况下如何处理 realpath 的结果也很重要。我已经看到它在很多情况下都做错了......
【解决方案4】:

使用正则表达式验证 ..//../ 的字符串,如果正则表达式返回 true,则不接受该字符串:

function validatePath($path) {
    if(preg_match('#\/\.\.\/#',$path))
        return False;
}

【讨论】:

  • 扔一个多字节..你就完蛋了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-27
  • 2017-07-06
  • 2018-06-10
  • 2011-09-11
  • 2014-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多