0

我收到了其他人的系统代码,该系统在您的浏览器中显示带有照片的文件夹。

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

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 变为 / 并且页面仍显示根文件夹。英语不是我的第一语言,所以我可能会误解 realpath 的工作原理或它的作用。据我了解,它会从给定的 URL 中删除 ../ 的任何实例。

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

4

2 回答 2

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");
于 2014-01-08T20:14:36.023 回答
1

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

不,这不是它的作用。它不是用于 URL,而是用于路径。它只是转换路径并将 ../ 扩展为正确的文件夹。它不会删除它们,它会解决它们 - 这意味着它会计算 ../ 代表什么并改变路径以获取它。

它还会在 Windows 上将 / 更改为 \。

真实路径

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

于 2014-01-08T20:12:51.293 回答