VirtualPath
庫可規範路徑並防止目錄遍歷攻擊,而無需查詢檔案系統。
建議使用依賴管理器 Composer 安裝rayne/virtual-path
。
composer require rayne/virtual-path
VirtualPath
類別將輸入規範化為絕對virtual path ,而無需查詢任何檔案系統。它還會偵測並標記目錄遍歷攻擊。
JailedPath
類別利用VirtualPath
建置可用於處理真實檔案的安全路徑。規範化是相對於名為 path 的jail
完成的,該監獄用作用戶輸入的任何路徑的虛擬根。由於JailedPath
不查詢檔案系統,因此它適合使用本地、遠端或虛構路徑。
請閱讀“實施細節”部分以了解更多詳細資訊。
TL;DR如有疑問,請使用JailedPath
類別。
JailedPath
在此範例中,網站訪客可以透過指定相對路徑作為GET
參數來從本機目錄/test
下載任何檔案。為了防止使用者透過目錄遍歷攻擊離開目錄,使用JailedPath
和/test
作為虛擬根目錄。
<?php
use Rayne VirtualPath JailedPath ;
$ jailedPath = new JailedPath ( ' /test ' , $ _GET [ ' path ' ] ?? '' );
if ( $ jailedPath -> hasJailbreakAttempt ()) {
// Log jailbreak attempt, ban user, …
return ;
}
if ( is_file ( $ jailedPath -> getAbsolutePath ())) {
@ readfile ( $ jailedPath -> getAbsolutePath ());
}
下表顯示如何規範化使用者定義的路徑以及如何相對於虛擬根解釋它們。
使用者輸入 | hasJailbreakAttempt() | getAbsolutePath() | getRelativePath() |
---|---|---|---|
空字串 | false | /test | 空字串 |
. | false | /test | 空字串 |
a.png/../b.png | false | /test/b.png | b.png |
/a/./b | false | /test/a/b | a/b |
.. | true | /test | 空字串 |
../example | true | /test/example | example |
../etc/passwd | true | /test/etc/passwd | etc/passwd |
大批 | true | /test | 空字串 |
VirtualPath
如果不需要固定前綴或JailedPath
的糖衣,那麼VirtualPath
就足夠了,因為它是用於規範化路徑的類別。 VirtualPath
對輸入進行規範化,並提供可信(規範化,帶有前導/
)和不可信(可能是惡意用戶輸入的字串表示形式)路徑。
當VirtualPath
實例(可(string)
轉換)附加到虛擬根目錄時,可以使用VirtualPath
輕鬆重新建立前面的範例。
<?php
use Rayne VirtualPath VirtualPath ;
$ path = new VirtualPath ( $ _GET [ ' path ' ] ?? '' );
$ absolutePath = ' /test ' . $ path ;
根據使用場景,即使原始輸入不可信,有時使用標準化可信任路徑也很有用,例如,當明確支援相對路徑並在意外嘗試存取virtual path之外的檔案時給用戶帶來懷疑的好處。
注意: VirtualPath
傳回帶有前導/
規範化路徑。處理檔案時,建議新增受信任路徑作為前綴(請參閱目前部分中的程式碼範例),否則將引用相對於檔案系統根的檔案。為了不忘記添加前綴,請在處理實際文件時使用JailedPath
類別。
輸入 | isTrusted() | getTrustedPath() | getUntrustedPath() |
---|---|---|---|
大批 | false | / | 空字串 |
空字串 | true | / | 空字串 |
../articles | false | /articles | ../articles |
tags/../../articles | false | /articles | tags/../../articles |
tags/../articles | true | /articles | tags/../articles |
../etc/passwd | false | /etc/passwd | ../etc/passwd |
/etc/passwd | true | /etc/passwd | /etc/passwd |
etc/passwd | true | /etc/passwd | etc/passwd |
使用純虛擬標準化路徑有不同的好處:
路徑規範化無需查詢檔案系統即可完成
不可能對virtual path範圍以外的檔案進行定時攻擊
不需要複雜的比較來將目錄遍歷限制為特定目錄及其子目錄
僅有的.
、 ..
、 (標準化為
/
)和/
被解釋為路徑標準化
沒有意外和資訊外洩~
其他庫中看到的擴展
VirtualPath
的實作不會解釋、變更或刪除控製字元和 Unicode:
某些系統上允許目錄和檔案路徑包含控製字符
刪除控製字元超出了庫的範圍
克隆儲存庫
git clone https://github.com/rayne/virtual-path.git
安裝開發依賴項
composer install --dev
運行測試
composer test