我正在帮助我的朋友保护他的网站。他给了我源文件,我发现了一些东西,在我看来,可能会导致许多问题,但是,像以前一样,我的朋友说这部分代码是安全的:
if(is_file('foo/' . $_POST['f'] . '/bar/foo.php'))
{
include('foo/' . $_POST['f'] . '/bar/foo.php');
}
我向他证明我可以绕过include()
功能,但他说,is_file()
这部分代码是100%安全的,请帮我证明代码不安全或者说服我这个代码是安全的。
此代码绕过include()
函数(WINDOWS):
curl_setopt($ch, CURLOPT_POSTFIELDS, 'f=../foo/bar.php' . str_repeat('.', 4086)); // without is_file() check this request leads to LFI
但is_file()
仍然返回false
答案 0 :(得分:2)
避免使用此类结构。如果攻击者能够将自己的PHP文件放在服务器上(甚至在WWW根目录之外,例如,在tmp文件夹中),他就可以使用Web服务器的权限执行它。
答案 1 :(得分:2)
如果文件不存在,include
无论如何都不会包含它。在它之前进行is_file
检查是多余的,并且不会添加任何安全性。如上所述,包含基于用户输入的任意文件总是一个坏主意和安全漏洞;是否仔细检查文件是否存在。
答案 2 :(得分:2)
is_file
和include
有一个缺陷,可以prematurely end the string by using a null byte。
因此,根据PHP版本,使用以下POST进行POST可能会打印出任意文件:
f=../../../../../etc/passwd%00
自PHP 5.3.4起,所有文件系统功能都被认为不受空字节中毒的影响。
答案 3 :(得分:1)
我的朋友说这部分代码是安全的
如果你的朋友是权威 - 并且你在这里问这个问题听起来有点像他 - 你应该更好地倾听他的意见并遵循他的道路 - 对或错。这就是朋友们的意思:我们允许彼此犯错误。
除此之外,为$_POST['f']
中的允许值创建白名单以结束任何讨论。这样做会要求您制定确切的规范,这些规范在此限定了有效路径,而不是。
当不清楚您想要保护什么时,您无法为参数带来安全性。