考慮以下經典問題的情況下:dirname是否足以防止目錄遍歷攻擊?
<?php
$filename = "/tmp/".$_GET['f'];
readfile($filename);
此代碼是易受directory traversal attack,例如,如果的$_GET['f']
值爲../etc/shadow
的該文件的內容將被公開給攻擊者。
有一些衆所周知的方法來防止這種類型的攻擊;我不問如何做到這一點。問題是:以下是用dirname
防彈的方法來防止這種攻擊嗎?
<?php
if (dirname($_GET['f']) != '.') die ('Attack prevented');
它聽起來像它應該是因爲dirname
:
- 回報
.
,當且僅當在輸入路徑中沒有斜槓(在線文檔,使一個不太嚴格的保證,但the source是明確的) - 是二進制安全的(所以不能被嵌入的空值欺騙)
所以,據我所知道的,攻擊的唯一可能的途徑將是在編碼數據$_GET['f']
通過這樣,要麼性格/
或\
(讓我們不要忘記的Windows)編碼的東西,不不包含相應的字符和的ASCII值必須同時被底層C運行時庫的fopen
函數透明地支持。
無ASCII值限制排除了所有的單字節編碼,UTF-8和UTF-16的兩種風格;此外,由於C運行時的規範與平臺無關,因此攻擊只能適用於某些使用「易受攻擊」編碼來表示名稱的文件系統。據我所知,這種文件系統並不存在;任何人都難以創造它;最後PHP不會託管在這樣一個假設的外來系統上,即使它存在。
總之,在我看來,這個檢查是 100%安全。有什麼我錯過了嗎?
我用的代碼從這個【答案】(http://stackoverflow.com/a/4205278/453348),你也可以從這個問題 – tttony
@tttony檢查'MainMa'回答:謝謝,但正如我上面所說的,我知道如何防止這種攻擊。問題是,它可以自信地防止*這種方式*? – Jon
根據我的測試,你的方法工作,看起來很簡單,但它的工作 – tttony