考虑以下经典问题案例:
这段代码存在目录遍历攻击漏洞,例如如果
有已知的方法来防止这种类型的攻击,我不会问如何做到。问题是:
<?php
$filename = "/tmp/".$_GET['f'];
readfile($filename);
这段代码存在目录遍历攻击漏洞,例如如果
$_GET['f']
的值为../etc/shadow
,攻击者将会看到该文件的内容。有已知的方法来防止这种类型的攻击,我不会问如何做到。问题是:
dirname
的以下用法是否是防御攻击的万无一失之举?
<?php
if (dirname($_GET['f']) != '.') die ('Attack prevented');
听起来应该是由于dirname
的原因:
- 仅当输入路径中没有斜杠时(在线文档提供了不太严格的保证,但源代码是明确的)才返回
.
- 是二进制安全的(因此无法被嵌入的空值欺骗)
因此,据我所知,唯一可能的攻击途径就是以某种编码将数据传递给$_GET['f']
,使得字符/
或\
(别忘了Windows)编码为不包含相应字符ASCII值的内容,并且同时这种编码必须被底层C运行时库的fopen
函数透明地支持。
不允许使用非ASCII值,这就排除了所有单字节编码、UTF-8和UTF-16的两种格式;此外,由于C运行时规范是平台无关的,攻击只能适用于某些使用“易受攻击”的编码来表示名称的文件系统。据我所知,这样的文件系统不存在;即使存在,也几乎没有任何人会创建它;最后,即使它存在,PHP也不会在这种假想的异国情调系统上托管。
总之,我认为这个检查是100%安全的。我有什么遗漏吗?
MainMa
答案。 - tttony