【发布时间】:2013-10-27 03:38:43
【问题描述】:
考虑以下经典问题案例:
<?php
$filename = "/tmp/".$_GET['f'];
readfile($filename);
此代码易受directory traversal attack 的攻击,例如,如果$_GET['f'] 的值为../etc/shadow,则该文件的内容将被泄露给攻击者。
有一些众所周知的方法可以防止这种类型的攻击;我不是在问如何做到这一点。问题是:下面使用dirname 是防止攻击的防弹方法吗?
<?php
if (dirname($_GET['f']) != '.') die ('Attack prevented');
它听起来应该是dirname:
- 当且仅当输入路径中没有斜杠时才返回
.(在线文档的保证不那么严格,但the source是明确的) - 是二进制安全的(因此不会被嵌入的空值欺骗)
据我所知,唯一可能的攻击途径是将数据传递给$_GET['f'],其编码方式使得字符/ 或\(别忘了Windows)编码为某种东西不包含相应字符和的ASCII值,同时底层C运行时库的fopen函数必须透明地支持这种编码。 p>
无 ASCII 值限制排除了所有单字节编码、UTF-8 和两种 UTF-16 风格;此外,由于 C 运行时的规范与平台无关,因此攻击只能适用于某些使用“易受攻击”编码来表示名称的文件系统。据我所知,这样的文件系统并不存在。任何人都很难创造它;最后,即使存在这样一个假设的奇异系统,PHP 也不会托管在它上面。
总之,在我看来,这个检查是 100% 安全的。有什么我错过的吗?
【问题讨论】:
-
我已经使用了answer 中的代码,您也可以查看该问题的
MainMa答案 -
@tttony:谢谢,但正如我上面所说,我知道如何防止攻击。问题是,以这种方式可以自信地阻止它吗?
-
根据我的测试,你的方法有效,看起来简单但有效
标签: php security encoding url-parameters directory-traversal