簡體   English   中英

如何確保文件路徑在給定的子目錄中?

[英]How do I make sure a file path is within a given subdirectory?

我想確保通過查詢字符串設置的文件路徑不會超出所需的子目錄。 現在,我正在檢查:

  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");
}

我擔心的是惡意用戶會看到網址,並嘗試執行類似“ view_sample.php?path=../../database/connection_info.php ”的操作,並獲取對“樣本”中存在的文件的訪問權限目錄。

我在上面定義的四個檢查(將在path_is_valid()函數中實現)是否足以鎖定惡意用戶? (另外,我認為支票1,3和4基本上是無關緊要的,因為我在前面設置相對路徑,但是如果我不這樣做,那么檢查是否足夠?)

呼叫

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

然后檢查生成的路徑是否以您期望的目錄開頭。

<?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!";
    }
?>

使用realpath不應該改變路徑,所以我用以下方式使用它:

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));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM