我的朋友在我的腳本中發現了一個問題,它提供了對根文件的訪問。PHP安全根
該網址提供了passwd文件:
http://site.com/attachment.php?file=../../../../../../etc/passwd
如何逃離這個安全漏洞?
我的朋友在我的腳本中發現了一個問題,它提供了對根文件的訪問。PHP安全根
該網址提供了passwd文件:
http://site.com/attachment.php?file=../../../../../../etc/passwd
如何逃離這個安全漏洞?
有幾種不同的解決方案。 如果只能有一個文件名,則basename()解決方案將起作用。
然而,如果它可以是路徑,一個更復雜的解決方案是需要
//assume current directory, but can be set anything. Absolute path of course
$basedir = dirname(__FILE__);
//assume our files are below document root.
//Otherwise use it's root dir instead of DOCUMENT_ROOT
$filename = realpath($_SERVER['DOCUMENT_ROOT'].$_GET['file']);
if (substr($filename,0,strlen($basedir)) !== $basedir) {
header ("HTTP/1.0 403 Forbidden");
exit;
}
也有一個有用的PHP配置選項open_basedir
不要使用URL字符串下載文件....定義唯一的ID來表示文件而不是路徑。
你可能已經看到像這樣的下載http://www.mysite.com/download.php?id=23423
他們做了什麼,使用這個ID,從數據庫中取出文件名和路徑,然後下載它。
我想你有一個存放所有附件的目錄。
只需測試文件是否位於您的目錄中。
// http://www.php.net/manual/en/function.basename.php
// http://cz.php.net/manual/en/function.file-exists.php
if (file_exists($attachments_path . "/" . basename($_GET['file'])) {
// do work
}
Starx發佈了一個解決方案,看起來很好。不過,它可以在沒有數據庫的情況下完成。如果有人上傳文件,您可以將該文件存儲爲md5($filename).$extension
並使用您的腳本。
附件目錄中有一個名爲「passwd」的文件,代碼還允許下載/ etc/passwd文件?我不是PHP程序員,但我認爲你應該更明確地說要訪問的文件應該以相同的方式形成: $ filename = $ attachments_path。 「/」。基本名($ _ GET [ '文件']) – 2010-08-22 18:01:02
您可以使用realpath()
和dirname()
來檢查針對$_SERVER['DOCUMENT_ROOT']
(或任何下載的「安全」目錄)的URL。
如果realpath()
的結果指向安全目錄之外,則可以拒絕下載請求。
還有open_basedir安全指令(以及從5.3開始的運行時選項)。
*(參考)* HTTP://en.wikipedia。 org/wiki/Directory_traversal – Gordon 2010-08-22 10:18:40
正如@Starx指出的那樣,儘量避免使用文件路徑作爲文檔的標識符(除目錄遍歷外,還有其他問題)。 (@MartIX有關(md5)散列的想法可能有助於精益實施)。此外,這是一個好主意**不要以root身份運行你的服務器。使用一個單獨的用戶,他們只具有系統上完成任務所必需的權限。 – zpea 2012-04-13 21:35:18
(這就是說,如果你的意思是可以訪問root用戶只能讀取的文件,比如'/ etc/shadow',那麼當前Unix中的任何用戶都可以讀取'/ etc/passwd') – zpea 2012-04-13 21:42:14