Php 基于URL数据的安全性和包含

Php 基于URL数据的安全性和包含,php,security,include,Php,Security,Include,以下包含声明是否存在安全风险 include "pages/".$_GET["page"].".php"; 如果是: -为什么? -什么是更安全的方法?是的。首先,在没有某种验证的情况下,永远不要直接使用GET变量 此外,您不应该允许包含任意的路径规范 相反,如果绝对需要如此多的动态性,则应该直接将include限制为某个目录中的路径(并检查指定的路径是否引用该目录中的文件),或者应该传递引用希望包含的内容的标记(然后执行类似于查找关联数组的操作,以查看给定标记引用的文件) 后者的一个例子如下

以下包含声明是否存在安全风险

include "pages/".$_GET["page"].".php";
如果是:
-为什么?

-什么是更安全的方法?

是的。首先,在没有某种验证的情况下,永远不要直接使用GET变量

此外,您不应该允许包含任意的路径规范

相反,如果绝对需要如此多的动态性,则应该直接将include限制为某个目录中的路径(并检查指定的路径是否引用该目录中的文件),或者应该传递引用希望包含的内容的标记(然后执行类似于查找关联数组的操作,以查看给定标记引用的文件)

后者的一个例子如下:

$allowed_pages = array(
  "page1" => "pages/page1.php",
  "page2" => "pages/page2.php",
  "foobar" => "pages/page7.php",
  "stuff" => "pages/blarg.php"
);

$page = $_GET['page'];
if(array_key_exists($allowed_pages, $page)) {
  include($allowed_pages[$page]);
}

(在这种情况下,只允许指定的键这一事实对可能包含的内容起到了验证和限制的作用。)

这是一种风险,因为在
$\u GET[“page”]
中可以是一个您不需要的路径,例如
。/../settings.php

应该这样做:

$allowedPages = array('news', 'contact', ...);
if ( in_array($_GET["page"], $allowedPages) ) {
    include "pages/".$_GET["page"].".php";
} else {
    throw new Exception('Page is not valid !');
}

检查文件是否存在也是一件好事。

您实际上是在让他们能够执行系统中存在的任何PHP。这是一个很大的未知问题


从根本上说,这是有风险的,因为即使现在没有“危险”代码指向,将来也可能有。

除了有一个白名单,您还可以这样做

$include = $_GET['page'];

if ( ! preg_match('/^[a-z-_]+$/i', $include)) {
    throw new Exception('Access denied');
}
包括“pages/”$\u GET[“page”]。“.php”

您硬编码前缀的事实可以防止以下攻击:

?page=http%3A%2F%2Fwww.blackhat.com%2Fbad.code%3F

但是,由于$_GET['page']可能包含“…”,因此有人可以强制从您的系统中包含任何具有php扩展名的文件。您确信这永远不会导致安全问题吗

按照其他人的建议使用白名单安全得多,而且还消除了为避免远程包含漏洞而在路径前面加前缀的要求


C.

他们可以读取任何文件,因为php中的include不必包含php代码。如果没有,php只会将文件的内容转储到其中。当然也应该注意到这一点!这里有更多关于如何利用此类内容的示例:注释也有很多内容。