一个常见的漏洞是 Web 应用程序接受文件系统路径作为请求参数,然后对指定路径执行一些操作。例如,检索文件并将其返回给用户,或者甚至可能写入/删除文件。这可能允许恶意用户访问他们不应访问的文件,例如源代码、密码文件等。
即使您预先添加基本路径,这也可能是一个问题,因为攻击者可以使用../
(*nix) 和..\
(Windows) 等目录遍历序列从基本路径向上遍历并进入受限制的目录和文件。
那么,一般的想法是要么彻底禁止任何这样的遍历序列,要么“规范化”包含这些序列的路径,然后检查它们是否仍然落在基本路径内。
从我的理解,试图在请求参数黑名单遍历序列是困难的,因为有备用网址和Unicode编码(例如%2e%2e%2f
,和许多,许多其他)最终可能会由Web服务器被解释为../
或..\
。
但是,如果我们在网络服务器(例如,Apache)接收到路径并传递给我的应用程序之后对其进行规范化,那么替代编码是否仍然是一个问题?例如,使用这些规范化规则?
我的理由是,无论网络服务器接收%2e%2e%2f
并将其解码为../
,还是网络服务器直接接收../
,规范化算法都会../
在检查基本目录之前查看并解析/过滤它。即使攻击者使用类似 的双重编码%252e%252e%252f
,它也会被解码为%2e%2e%2f
,操作系统/文件系统将逐字处理。
但是,在这个问题中,它表明:
但是,如果 Web 服务器正在提供文件并且解码 unicode 是在防止目录遍历的检查之后完成的,或者由操作系统完成的稍有不同,则此攻击可能会通过过滤器,从而允许攻击起作用。
因此,换句话说,是否有任何已知的字符序列可以使其通过 Web 服务器的解码和上述规范化例程(处理../
或..\
),可以被操作系统或较低级别的文件处理函数解释为目录遍历?
例如,在 PHP 中:
$base = "/path/to/allowed/directory/";
$path = $_GET['path'];
$normalizedPath = normalize($path); // normalize will remove or resolve ../ and ..\
$fullPath = $base . $normalizedPath;
echo file_get_contents($fullPath);