$_SERVER['REQUEST_URI']
包含请求的URI路径和查询字符串,因为它出现在HTTP request line中。因此,当请求http://example.com/foo/bar?baz=quux
并且服务器将请求传递给脚本文件/request_handler.php
时,$_SERVER['REQUEST_URI']
仍然是/foo/bar?baz=quux
。我用mod_rewrite的任何请求映射到request_handler.php
如下:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule^/request_handler.php
所以正确性,在文件系统路径中使用$_SERVER['REQUEST_URI']
之前,你需要摆脱查询字符串。您可以使用parse_url
这样做:
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
但由于该值从没有事先路径解析HTTP请求行来直接,但它仍然会含有类似..
象征性的路径段。
但是,由于所请求的URI路径已经是绝对路径引用,并且请求http://example.com/etc/passwd
应导致包含/etc/passwd
,所以甚至不需要路径遍历。
所以这实际上是一个local file inclusion vulnerability。
现在要解决这个问题,需要一个使用method的特定根目录,这是你的一个很好的改进。但你实际上需要$basedir
前缀是:
$path = realpath($basedir . $_SERVER['REQUEST_URI_PATH']);
if ($path && strpos($path, $basedir) === 0) {
include $path;
}
该解决方案提供了一些承诺:
$path
是一个有效的,解决了现有的文件,或false
路径;
- 只有在
$basedir
是$path
的前缀路径时才会包含该文件。
但是,这仍然允许访问使用其他种类的access control like the one provided by Apache’s mod_authz_host module保护的文件。
如何将请求的URI会是什么样子,你如何映射请求的路径,你的PHP文件? – Gumbo 2013-04-20 21:11:08
你可以在request_uri中传递任何你想要的东西,包括html/javascript。这取决于您和您的代码以确保安全使用该值。您应该**永远不要**允许用户指定将用于包含/需要的路径,无论您认为安全性有多好。就像现在这样,他们碰到了'http://yoursite.com/http:// malicioussite.com/remote_takeover.php',它以文本格式输出php代码,并且您的服务器完全被彻底颠覆。 – 2013-04-20 21:15:53
你的代码看起来并不像你特别关心它的安全性。这是允许用户注入数据的一个很好的例子。至少要对白名单进行过滤,并找到更多的无法注入无效路径的对策。是的,您可以通过请求URI传递点。这是一个标准变量,只是设置或取消设置。 – 2013-04-20 21:36:12