5

我想确保通过查询字符串设置的文件路径不会超出所需的子目录。现在,我正在检查:

  1. 路径不以“ /”开头,防止用户给出绝对路径。
  2. 该路径不包含“ ..”,以防止用户提供位于所需子目录之外的路径。
  3. 路径不包含“ :”,防止使用url(即“ http://”、“ ftp://”等)。如果我曾经在 Windows 服务器上运行这个脚本(不太可能),这也会阻止以驱动器说明符(即“ C:\”)开头的绝对路径。注意:我知道冒号是 Unix 文件名中的有效字符,但我永远不会在文件名中使用它。
  4. 路径不以“ \”开头。以防万一我改变主意在 Windows 服务器上运行,这可以防止指定 Windows 网络路径(即“ \\someserver\someshare”)。同样,我知道反斜杠是有效的 Unix 文件名字符,但我也不会在任何文件名中使用它。

这些检查是否足够?

背景

我有一个 PHP 脚本,它(通过查询字符串)获取要显示给用户的示例源文件的路径。所以我可能会给他们一个“ view_sample.php?path=accounting_app/report_view.php”或“ view_sample.php?path=ajax_demo/get_info.js”之类的链接。

该脚本看起来基本上是这样的:

$path = $_GET['path'];
if(path_is_valid($path) && is_file("sample/$path"))
{
  header('Content-Type: text/plain');
  readfile("sample/$path");
}

我担心的是恶意用户会看到 url 并尝试执行类似“ view_sample.php?path=../../database/connection_info.php”的操作并获得对不在“sample”目录中的文件的访问权限。

我上面定义的四项检查(将在path_is_valid()函数中实现)是否足以锁定恶意用户?(另外,我认为检查 1、3 和 4 基本上是无关紧要的,因为我预先设置了一个相对路径,但如果我不这样做,检查就足够了吗?)

4

3 回答 3

10

称呼

$path = realpath("sample/$path");

然后检查生成的路径是否以您期望的目录开头。

于 2009-01-19T04:50:43.900 回答
6
<?php
    // Current path information
    $path = $_GET['path'];
    $vroot = "sample";

    // Validate that the $path is a subfolder of $vroot
    $vroot = realpath($vroot);
    if(substr(realpath($path), 0, strlen($vroot)) != $vroot or !is_dir($path)) {lid!
        exit("Invalid path");
    } else {
       echo "Ah, everything is alright!";
    }
?>
于 2009-01-19T05:39:52.210 回答
0

The use of realpath should not change the path, so I use it in the following way:

function checkPath($pathToCheck) {
    global $basepath;
    $fullpath = $basepath.'/'.$pathToCheck;
    if ($fullpath==realpath($fullpath) && is_dir($fullpath)) {
        return $fullpath;
    } else {
        error_die('path not allowed: '.htmlentities($pathToCheck));
    }
}
于 2017-02-26T09:41:18.937 回答