Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/255.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于请求的PHP包含_Php_Security - Fatal编程技术网

基于请求的PHP包含

基于请求的PHP包含,php,security,Php,Security,使用$\u SERVER['REQUEST\u URI']包含文件是否涉及任何安全风险?您能否以某种方式通过请求uri传递。/../.. 我的想法是这样的: <?php $path = $_SERVER['REQUEST_URI']; $path = preg_replace('~\\.html?$~', '.php', $path); include $path; ?> 这应该用“.htm”或“.html”URI替换“.php”路径并呈现它们。但我担心这里的安全问题。这实际上

使用
$\u SERVER['REQUEST\u URI']
包含文件是否涉及任何安全风险?您能否以某种方式通过请求uri传递
。/../..

我的想法是这样的:

<?php
$path = $_SERVER['REQUEST_URI'];
$path = preg_replace('~\\.html?$~', '.php', $path);
include $path;
?>


这应该用“.htm”或“.html”URI替换“.php”路径并呈现它们。但我担心这里的安全问题。

这实际上并没有回答这个问题…

请注意,您可以确保请求uri指向当前工作目录中的实际有效文件路径。您可以使用
realpath
函数来规范化路径

下面的代码可以实现此目的:

<?php
$basedir = getcwd();

$path = $_SERVER['REQUEST_URI'];
$path = preg_replace('~\\.html?$~', '.php', $path);
$path = realpath($path);

if ($path && strpos($path, $basedir) === 0) {
    include $path;
} else {
    return false;
}
?>


这里我使用了
strpos
来验证
$path
是否以
$basepath
开头。由于
realpath
将删除任何
。/../..
有趣的业务,这将安全地将您保存在
$basepath
目录中。

这实际上并没有回答问题…

请注意,您可以确保请求uri指向当前工作目录中的实际有效文件路径。您可以使用
realpath
函数来规范化路径

下面的代码可以实现此目的:

<?php
$basedir = getcwd();

$path = $_SERVER['REQUEST_URI'];
$path = preg_replace('~\\.html?$~', '.php', $path);
$path = realpath($path);

if ($path && strpos($path, $basedir) === 0) {
    include $path;
} else {
    return false;
}
?>


这里我使用了
strpos
来验证
$path
是否以
$basepath
开头。由于
realpath
将删除任何
。/../../
有趣的业务,这将安全地将您保存在
$basepath
目录中。

$\u服务器['REQUEST\u URI']
包含请求的URI路径和查询字符串,正如它在。所以当
http://example.com/foo/bar?baz=quux
被请求,服务器将请求传递到脚本文件
/request\u handler.php
$\u服务器['request\u URI']
仍然是
/foo/bar?baz=qux
。我使用mod_rewrite将任何请求映射到
request_handler.php
,如下所示:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /request_handler.php
因此,为了确保正确性,在文件系统路径中使用
$\u SERVER['REQUEST\u URI']
之前,您需要去掉查询字符串。您可以使用
parse_url
执行此操作:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
但是,由于此值直接来自HTTP请求行而没有事先的路径解析,因此它可能仍然包含符号路径段,如

但是,甚至不需要路径遍历,因为请求的URI路径已经是绝对路径引用,并且请求
http://example.com/etc/passwd
应导致包含
/etc/passwd

所以这实际上是一个很好的例子

现在要解决这个问题,需要使用您chowey提供的根目录,这是一个很好的改进。但实际上您需要在它前面加上
$basedir

$path = realpath($basedir . $_SERVER['REQUEST_URI_PATH']);
if ($path && strpos($path, $basedir) === 0) {
    include $path;
}
该解决方案提供了几个承诺:

  • $path
    是现有文件的有效解析路径,或者
    为false
  • 只有当
    $basedir
    $path
    的前缀路径时,才会包含该文件

但是,这仍然允许访问使用其他类型的保护的文件。

$\u服务器['REQUEST\u URI']
包含请求的URI路径和查询字符串,正如它在列表中显示的那样。所以当
http://example.com/foo/bar?baz=quux
被请求,服务器将请求传递到脚本文件
/request\u handler.php
$\u服务器['request\u URI']
仍然是
/foo/bar?baz=qux
。我使用mod_rewrite将任何请求映射到
request_handler.php
,如下所示:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /request_handler.php
因此,为了确保正确性,在文件系统路径中使用
$\u SERVER['REQUEST\u URI']
之前,您需要去掉查询字符串。您可以使用
parse_url
执行此操作:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
但是,由于此值直接来自HTTP请求行而没有事先的路径解析,因此它可能仍然包含符号路径段,如

但是,甚至不需要路径遍历,因为请求的URI路径已经是绝对路径引用,并且请求
http://example.com/etc/passwd
应导致包含
/etc/passwd

所以这实际上是一个很好的例子

现在要解决这个问题,需要使用您chowey提供的根目录,这是一个很好的改进。但实际上您需要在它前面加上
$basedir

$path = realpath($basedir . $_SERVER['REQUEST_URI_PATH']);
if ($path && strpos($path, $basedir) === 0) {
    include $path;
}
该解决方案提供了几个承诺:

  • $path
    是现有文件的有效解析路径,或者
    为false
  • 只有当
    $basedir
    $path
    的前缀路径时,才会包含该文件

但是,这可能仍然允许访问使用其他类型保护的文件。

在检查基本路径之前,确实不要信任$\u服务器['REQUEST\u URI']


如果攻击者了解过滤过程,则不要制作从路径中删除../的过滤器。在检查基本路径之前,确实不要信任$_服务器['REQUEST_URI']


并且不要制作一个从路径中移除../的过滤器。如果攻击者了解过滤器过程,他们可以设计一种nieuw注入方式。

我有同样的问题,并根据Gumbo的回答选择了以下操作:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

$path = realpath(FOLDER_ROOT . $_SERVER['REQUEST_URI_PATH']);

$directory_white_list_array = array('/safe_folder1', '/safe_folder1/safe_folder2');

if ($path && strpos($path, FOLDER_ROOT) === 0 && (in_array(dirname($path), $directory_white_list_array)  && ('php' == pathinfo($path, PATHINFO_EXTENSION)))) {
    include $path;
}else{
    require_once FOLDER_ROOT."/miscellaneous_functions/navigation_error.php";
    navigation_error('1');
}
总结:
添加了目录白名单和.php扩展限制。

我也有同样的问题,根据Gumbo的回答,我选择做以下事情:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

$path = realpath(FOLDER_ROOT . $_SERVER['REQUEST_URI_PATH']);

$directory_white_list_array = array('/safe_folder1', '/safe_folder1/safe_folder2');

if ($path && strpos($path, FOLDER_ROOT) === 0 && (in_array(dirname($path), $directory_white_list_array)  && ('php' == pathinfo($path, PATHINFO_EXTENSION)))) {
    include $path;
}else{
    require_once FOLDER_ROOT."/miscellaneous_functions/navigation_error.php";
    navigation_error('1');
}
总结:
添加了目录白名单和.php扩展限制。

请求的URI是什么样子,以及如何将请求的路径映射到php文件?您可以在请求URI中传递任何需要的内容,包括html/javascript。由您和您的代码来确保安全使用该值。您永远不应该允许用户指定将