$_SERVER['REQUEST_URI']
包含請求的URI路徑和查詢字符串,因爲它出現在HTTP request line中。因此,當請求http://example.com/foo/bar?baz=quux
並且服務器將請求傳遞給腳本文件/request_handler.php
時,$_SERVER['REQUEST_URI']
仍然是/foo/bar?baz=quux
。我用mod_rewrite的任何請求映射到request_handler.php
如下:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule^/request_handler.php
所以正確性,在文件系統路徑中使用$_SERVER['REQUEST_URI']
之前,你需要擺脫查詢字符串。您可以使用parse_url
這樣做:
$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
但由於該值從沒有事先路徑解析HTTP請求行來直接,但它仍然會含有類似..
象徵性的路徑段。
但是,由於所請求的URI路徑已經是絕對路徑引用,並且請求http://example.com/etc/passwd
應導致包含/etc/passwd
,所以甚至不需要路徑遍歷。
所以這實際上是一個local file inclusion vulnerability。
現在要解決這個問題,需要一個使用method的特定根目錄,這是你的一個很好的改進。但你實際上需要$basedir
前綴是:
$path = realpath($basedir . $_SERVER['REQUEST_URI_PATH']);
if ($path && strpos($path, $basedir) === 0) {
include $path;
}
該解決方案提供了一些承諾:
$path
是一個有效的,解決了現有的文件,或false
路徑;
- 只有在
$basedir
是$path
的前綴路徑時纔會包含該文件。
但是,這仍然允許訪問使用其他種類的access control like the one provided by Apache’s mod_authz_host module保護的文件。
如何將請求的URI會是什麼樣子,你如何映射請求的路徑,你的PHP文件? – Gumbo 2013-04-20 21:11:08
你可以在request_uri中傳遞任何你想要的東西,包括html/javascript。這取決於您和您的代碼以確保安全使用該值。您應該**永遠不要**允許用戶指定將用於包含/需要的路徑,無論您認爲安全性有多好。就像現在這樣,他們碰到了'http://yoursite.com/http:// malicioussite.com/remote_takeover.php',它以文本格式輸出php代碼,並且您的服務器完全被徹底顛覆。 – 2013-04-20 21:15:53
你的代碼看起來並不像你特別關心它的安全性。這是允許用戶注入數據的一個很好的例子。至少要對白名單進行過濾,並找到更多的無法注入無效路徑的對策。是的,您可以通過請求URI傳遞點。這是一個標準變量,只是設置或取消設置。 – 2013-04-20 21:36:12