PHP realpath无法阻止目录遍历

时间:2014-01-08 20:09:59

标签: php realpath directory-traversal

我收到了其他人的代码,系统会在浏览器中显示包含照片的文件夹。

例如,这是网站上可能的网址:

gallery.php?action=view&folder=Cars

目前,您可以使用../../../../../替换“Cars”,这将很乐意显示Linux根文件夹。幸运的是,该网站目前处于离线状态。

我尝试使用realpath来解决这个问题。这是我到目前为止所做的:

case 'view' :
$name = realpath(dirname(__FILE__) . "/Content/Gallery/" . $_GET['folder']);

echo $name;

$data = $file->getPictures($name);
require 'Views/Gallery.view.php';
break;

我在第三行添加了echo以查看URL是什么。在上面的url中,一切都很好,echo输出:

/var/www/Content/Gallery/Cars 

到目前为止,这么好。但是,如果我输入/../../../../../../../../而不是“Cars”,$ name变为/并且页面仍显示根文件夹。英语不是我的第一语言,所以我可能误解了真实路径的工作方式或工作原理。根据我的理解,它从给定的URL中删除../的任何实例。

有人可以告诉我我做错了吗?

2 个答案:

答案 0 :(得分:6)

realpath()不足以对抗目录遍历。

您所描述的内容非常简洁:它将../之类的相关内容转换为实际的目录路径。

但是,为了安全起见,您可以使用realpath() ed路径并查看是否仍然是安全基本路径的子项。如果不是,则有人试图潜行进入他们没有业务的目录:

 $name = realpath(dirname(__FILE__) . "/Content/Gallery/" . $_GET['folder']);

 // The safe root directory. 
 $safe_root = dirname(__FILE__) . "/Content/Gallery/";

 // Check whether realpath() result is still inside /Content/Gallery
 if (substr($name, 0, strlen($safe_root)) != $safe_root) 
   die ("Possible directory traversal attack");

答案 1 :(得分:1)

  

根据我的理解,它会从给定的URL中删除../的任何实例。

不,这不是它的作用。它不适用于URL,而是适用于路径。它只是转换路径并将../扩展到右侧文件夹。它不会删除它们,它会解析它们 - 这意味着它会计算../代表什么并改变它的路径。

它也会在Windows上更改为\。

realpath

  

realpath()展开所有符号链接并解析对输入路径中'/./','/../'和额外'/'字符的引用,并返回规范化的绝对​​路径名。