Php is_file()和本地文件包含漏洞

Php is_file()和本地文件包含漏洞,php,security,Php,Security,我正在帮助我的朋友保护他的网站。他给了我源文件,我发现了一些在我看来可能会引起很多问题的东西,但是,和以前一样,我的朋友说这部分代码是安全的: if(is_file('foo/' . $_POST['f'] . '/bar/foo.php')) { include('foo/' . $_POST['f'] . '/bar/foo.php'); } 我已经向他演示了我可以绕过include()函数,但他说,使用is_file()这部分代码是100%安全的,请帮助我向他演示代码不安

我正在帮助我的朋友保护他的网站。他给了我源文件,我发现了一些在我看来可能会引起很多问题的东西,但是,和以前一样,我的朋友说这部分代码是安全的:

if(is_file('foo/' . $_POST['f'] . '/bar/foo.php'))
  {
    include('foo/' . $_POST['f'] . '/bar/foo.php');
  }
我已经向他演示了我可以绕过
include()
函数,但他说,使用
is_file()
这部分代码是100%安全的,请帮助我向他演示代码不安全,或者让我相信这段代码是安全的

此代码绕过include()函数(WINDOWS):


但是
is_file()
仍然返回false

避免使用这种结构。如果攻击者能够将自己的PHP文件放在服务器上(甚至在WWW根目录之外,例如,在tmp文件夹中),他将能够使用web服务器的权限执行该文件。

如果该文件不存在,
include
无论如何也不会包含它。将
is_文件
检查放在冗余之前,不会增加任何安全性。如前所述,根据用户输入包含任意文件总是一个坏主意和安全缺陷;是否仔细检查该文件是否存在

is_文件
include
可能存在缺陷

因此,根据PHP版本的不同,发布包含以下内容的帖子可能会打印出任意文件:

f=../../../../../etc/passwd%00
只有在PHP5.3.4之后,所有文件系统函数才被称为对空字节中毒免疫

我的朋友说这部分代码是安全的

如果你的朋友是权威——让你这样问这个问题听上去有点像他——你最好听他的话,走他的路——对还是错。这就是朋友的作用:我们允许彼此犯错

除此之外,在
$\u POST['f']
中为允许的值创建一个白名单,以结束任何讨论。这样做将需要您制定确切的规范,说明什么是这里的有效路径,什么不是


当不清楚您想要保护什么时,您不能将安全性带到参数中。

它是不可利用的,但为什么这段代码在这里?什么用例会提示您像这样加载PHP文件?有一个if检查
is\u file
,所以它不会抛出任何东西。他唯一可以忽略的就是不包括文件。我认为最好检查
$\u POST['f']
因为黑客可以使用它来包含来自不同位置的文件,比如
'foo'./../foo2'./bar/foo.php'
,也可能是这个
'foo'./../foo2/someFileWhichWillCauseProblem.php?./bar/foo.php'
会导致包含
'foo'./../foo2/someFileWhichWillCauseProblem.php
,并带有额外参数
?/bar/foo.php
。这是危险的。所以它强烈建议您不要这样做。@imsiso,我试图添加“?”,但\u file()检查是否和以前一样有效。它返回false,那么,在哪种情况下“?”会起作用?。PHP返回:无法打开流:无效argument@imsi本地文件路径不包含、支持或解析
,这只与URL相关!您不能包含“带参数”的本地文件。谢谢,所以您认为有人可以绕过is_file()检查,对吗?是的,除了@Nickolay Olshevsky之外,我应该说喜欢上传带有有害代码的文件作为图像。(扩展名为.jpg、.png等)是的,如果他能够将其文件放在服务器上。这很容易编写switch()或一组if来选择所需的文件之一。也可以使用Windows的替代数据流利用这一点:使用
foo:bar
foo
由数据流名称
bar
引用。因此
f=../../../../../boot.ini:
也可以工作。
f=../../../../../etc/passwd%00