我应该如何防止 URL 中的相对路径尝试访问所服务目录之外的文件?

我应该如何防止 URL 中的相对路径尝试访问所服务目录之外的文件?

我如何确保自己免受如下相对路径的侵害:

/catalog.php?F=S&BrandCode=AE///index.php%3foption=com_g2bridge&controller=../%2520../../../../../../../../../../../../../../../proc/self/environ%2500

我最近在我的日志中发现了这些内容,虽然我知道这个不会有效,但我对如何防范此类威胁很感兴趣。

(使用 php5、apache2、debian)

答案1

许多不同的选择;

1)某种 preg_replace 表达式,用于删除双点、波浪连字符(我不记得它们叫什么,但它们看起来像 ~)、以 / 开头的路径等。

2)创建一组可以使用正则表达式或in_array等打开的允许的URL/路径。

3)启用 PHP 安全模式并设置 open_basedir 或 chroot PHP/Apache,这样它们就无法打开该树之外的任何文件

答案2

唯一能 100% 确保安全的方法就是永远不允许用户输入访问文件系统的命令。不要fopen($_GET['foo']),不要include($_POST['bar']),甚至不要mkdir($_COOKIE['baz'])。永远不要。就这样。没有任何借口。

如果您必须使用用户输入从文件系统中选择文件,请在数据库查找中使用用户输入(当然,在对数据库查询进行清理之后,以防止 SQL 注入),或者通过语句运行它switch;在这两种情况下,您都应该使用硬编码或软编码已知安全实际文件名的值,绝不用户输入本身的任何变化。

一切在 $_POST、$_GET、$_COOKIES、$_REQUEST 甚至 $_FILES 中(除了 'tmp_name' 和 'error' - 是的,'type' 是用户输入!)是您精确拥有的用户输入控制。所以永远不要相信它。甚至一些 $ 中的值服务器(例如“HTTP*' 值)是用户输入!不要让这些值靠近您的文件系统,也不要让它们靠近您的数据库,除非您先对它们进行转义(例如mysql_real_escape_string())或将它们绑定到准备好的语句(如果您使用的是 PDO)。

是的,您可以清理输入,但如果您忘记了什么怎么办?如果您忘记了波浪号 (~) 字符在 *nix 系统上有特殊含义怎么办?或者,如果您完美地清理了 Linux Web 服务器,但后来又转移到 Windows 服务器怎么办?或者,如果您从未预见到环境中发生了变化(例如出现了新的特殊字符),怎么办?等等。最安全、最面向未来的选择就是不要让用户输入靠近您的文件系统。

不过,要记住的一点是,有很多 Web 应用程序容易受到您在日志中看到的攻击。这并不意味着你的但是,服务器是:脚本小子经常会将他们的最新发现指向他们能找到的任何服务器,而不必先找出它们是否可能存在漏洞。如果您不存在漏洞,您就不必担心这种背景噪音。

答案3

我建议使用 chroot:

http://www.howtoforge.com/chrooting-apache2-mod-chroot-debian-etch

PS:清理 GET/POST/... 参数和输入当然也有帮助 ;)

相关内容