「在檔名的地方混入 ../,結果連伺服器深處的 .env 都能讀到」——這就是路徑遍歷。本文講解其原理與可靠的防範方法(不會寫出攻擊步驟)。
會出現在哪裡
凡是「用使用者輸入來選擇檔案」的地方都是候選。
| 功能 | 危險的用法 |
|---|---|
| 下載/預覽 | 把 ?file= 中的檔名原樣使用 |
| 圖片/附件的顯示 | 用 URL 參數拼出路徑的一部分 |
| 上傳 | 在保存目標路徑中使用使用者指定的名字(寫入型·最危險) |
| 範本/語言檔案讀取 | 用 ?lang= 等動態選擇檔案 |
為什麼會成立(原理)
../ 表示「向上一級目錄」。當應用程式把 公開資料夾 + 使用者輸入 原樣串接起來開啟檔案時,用疊加了 ../ 的輸入就能「走」出公開資料夾之外。
讀取會導致資訊外洩,寫入(上傳)則會被在任意位置放置檔案,有時還會發展為 RCE。
防禦:不把輸入用作路徑 + 限制在基準內
不把使用者輸入用作生檔案路徑(最重要)
要公開的檔案用 ID→實際檔案的對應表(白名單)來查。使用者傳入的只是「第 3 號」「invoice」等識別碼,實際路徑由伺服器決定。
正規化之後,務必確認「是否在基準目錄的內側」
用語言標準的路徑正規化(相當於 resolve/realpath)轉換為絕對路徑,並校驗它是否以所允許的基準目錄開頭。在外面就拒絕。../ 的簡單字串刪除存在編碼繞過,因此不可取。
以最小權限執行應用
把應用執行使用者能讀取的檔案收窄到業務所需的範圍。即便萬一被逃出,只要本來就讀不到,就不會產生危害。
把「不該交出的東西」放到公開根目錄之外
.env·.git·金鑰·備份,本來就不要放在 Web 根目錄或上傳資料夾裡。用設定消除攻擊面。
本站的視角:與設定失誤一脈相連。別弄錯堵漏的順序
路徑遍歷與 .env 公開的事故一脈相連。兩者都是「本不該經由 Web 送達的東西,卻經由 Web 送達了」的問題。用應急處置(回應標頭或簡單過濾)把「症狀」掩蓋起來,只要程式碼和設定沒修好,就會從別的路徑被穿出去。順序是①不把輸入用作路徑的程式碼 ②基準目錄內的檢查 ③根本上把祕密挪到公開根目錄之外。再配合閱讀 在共享租用伺服器上的安全設定,就能看清根本對策的形態。
接下來閱讀
- 事故:把 .env 整個公開出去的事故
- 對策:租用伺服器上的 .env 保護 / 術語:RCE 是什麼
FAQ
Q路徑遍歷會外洩什麼?
本來這個應用程式不應讓人接觸到的檔案。典型例子有 .env(資料庫憑證、API 金鑰)、設定檔、私鑰、原始碼、作業系統的 /etc 目錄下的檔案等。不僅是讀取,一旦被濫用於指定上傳目標路徑,還會被寫入到任意位置,進而可能發展為 RCE(任意程式碼執行)。
Q最主要的防禦是什麼?
就是「不把使用者的輸入原樣用作檔案路徑」。如果實在要用,就把它轉換為白名單(ID 或固定的檔名集合),並用函式庫對路徑進行正規化後,務必確認「它是否落在基準目錄的內側」。僅靠副檔名校驗或簡單地刪除 ../ 是會被繞過的。
Q用 .htaccess 或回應標頭堵上就行了嗎?
那只是針對「本不該交出的檔案被放在了公開目錄」這一另一個問題的應急處置。根本在於糾正設定「把應用本體、.env、.git 放到公開根目錄之外」,以及撰寫不把輸入用作路徑的程式碼。應急處置和根本對策是兩項不同的工作。