[英]How do I make sure a file path is within a given subdirectory?
我想確保通過查詢字符串設置的文件路徑不會超出所需的子目錄。 現在,我正在檢查:
/
”開頭,以防止用戶提供絕對路徑。 ..
”,以防止用戶提供所需子目錄之外的路徑。 :
”,以防止使用url(即“ http://
”,“ ftp://
”等)。 我是否應該在Windows服務器上運行此腳本(不太可能),這也將阻止以驅動器說明符開頭的絕對路徑(即“ C:\\
”)。 注意:我知道冒號是Unix文件名中的有效字符,但我永遠不會在文件名中使用它。 \\
”開頭。 為了防止我改變主意在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.