我如何防止来自php的远程文件包含攻击?

时间:2014-05-21 07:32:40

标签: php

这是我在index.php中的代码

include ($_GET['page']);

实际上我需要包含来自网址的网页<​​/ p>

"?page=go.php"
另一方面

我无法过滤

"?page=example.com"

至于某些情况我也需要包含这个值。但这是一个远程文件包含(RFI)漏洞。如何防止来自我网站的RFI攻击? 我正在做类似

的事情
$filename = $_GET['page'];
if (file_exists($filename)) {
{
include ($_GET['page']);
}

但它仅过滤

"?page=go.php"

这个短片的页面。

我被吮吸了
"?page=example.com"

这篇短片。

5 个答案:

答案 0 :(得分:5)

如果我正确理解了这个问题;你可以设置一个允许&#39;允许&#39;页面如:

  $allowedPages = array('go.php', 'stop.php', 'file.php');
  $filename = $_GET['page'];

  if(in_array($filename, $allowedPages) && file_exists($filename)){
    include ($filename);
  }else{
    //output error
  }

答案 1 :(得分:2)

我认为这个答案为时已晚,但对于那些可能会搜索此问题的人,我想也可以这样做:

1.定义完整路径的常量。

2.定义允许页面的白名单。

3.获取$ _GET变量,并将其转换为小写。

4.然后,如果$ _GET变量返回的页面在您的白名单数组中,则需要它,否则,将用户重定向到主页,并显示错误消息。

<?php
# this is abcd.php
define('SITE','http://www.yoursite.com/');
$allow = [SITE.'1.php', SITE.'2.php', SITE.'3.php'];
$get = strtolower(SITE.$_GET['page']);

if(in_array($get,$allow)){
    include $get;
} else {
    header('Location: index.php?param=incorrect');
}
?>

<?php
# this is index.php
if(isset($_GET['param']) && $_GET['param'] == 'incorrect'){
?>
    <script type="text/javascript">
        alert("INCORRECT PARAMETER PROVIDED");
    </script>
<?php
} else die('ERROR');

我并非100%确定这会在没有任何问题的情况下发挥作用,但我认为这是一个良好的开端,您可以随心所欲地找出适合您的内容。

答案 2 :(得分:1)

说实话,您创建dynamic网站的方法绝对不是您的选择。

要在这个问题的范围内回答,您可以执行以下操作:

您必须设置{**}允许**的whitelist个文件才能通过此功能加入。

看起来像这样:

<?php 

$whitelist = array(
    'file1.php',
    'file2.php',
    'file3.php',
    'file4.php',
    'file5.php',
);

?>

现在,在包含上述文件之前,您需要使用in_array()

进行检查
<?php 

if(in_array($_GET['page'] . '.php', $whitelist) && file_exists($_GET['page'] . '.php')) {
    include($_GET['page'] . '.php');
}

?>



这,你可以看到不是很漂亮! 另一种选择是做类似的事情:

    <?php 
    $file = strtolower($_GET['page']) . '.php';
    if(isset($whitelist[$file]) && file_exists($file)) {
        include($_GET['page'] . '.php');
    }

    ?>

答案 3 :(得分:0)

不接受page.php参数,只接受文件名。

"?page=go"

然后检查$ _REQUEST [“page”]是否为字母数字

if (ctype_alnum($_REQUEST["page"]))

并且不要在文件中提供非字母数字名称。

然后如果$ _REQUEST [“page”]上有file_exists,你就应该做得很好。

PS $ _REQUEST [“page”]与$ _GET [“page”]大致相同,它只与$ _POST相交

答案 4 :(得分:0)

您可以过滤其他域网址而不是过滤文件。 如果参数包含少于3个字母的主机名,则没有域是2个字母。

   $tmp= parse_url ($_GET['page']);
   if(strlen($tmp['host'])<3)
    include($_GET['page']);

如果有一些可信主机,那么您也可以验证它们。