開發者工具 · URL 編碼器和解碼器
URL 編碼不是淨化:解碼後的參數仍需要轉義
· 為什麼它很重要
url 編碼 安全 xss
百分比編碼保護 URL 結構,而不是 HTML、SQL 或 shell。這篇文章解釋了為什麼正確編碼的值在解碼時再次變得危險,以及哪種轉義屬於哪裡。
為什麼僅靠 URL 編碼無法阻止 XSS 攻擊
如果對傳輸進行編碼但在渲染之前進行解碼,「安全」參數可以執行腳本。考慮像 img 標籤這樣的 XSS 有效負載,其 onerror 處理程序百分比編碼為 %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E。如果它在 URL 中傳輸並在插入 HTML 之前由應用程式程式碼解碼,則瀏覽器會看到原始標記並執行處理程序。 Percent-encoding是表示層;不會改變潛在的威脅。
有效負載僅在傳輸過程中是安全的,此時它是對 HTTP 或 URL 解析器沒有特殊意義的編碼字串。一旦它被解碼,它就會再次變得危險,因為它會恢復到原來的形式。每個下游上下文必須應用適合其使用資料方式的自己的轉義規則。 URL 編碼不能取代 HTML 轉義、SQL 參數化或 shell 參數處理。
百分比編碼的用途是什麼-保持線路上的分隔符號明確,僅此而已
百分比編碼的作用是精確保護 URL 結構。 & 符號仍然是查詢字串語法的一部分,不會被重新解釋為分隔符號。斜線不會成為路徑分隔符號。問號不開始片段。透過將保留字元編碼為 %XX,解析器將它們視為資料,而不是語法。這適用於一項工作:保持網路上的 URL 結構明確。
解碼完全顛倒了那條單向街道。恢復的位元組正是編碼的內容,不多也不少。 HTML 危險字串仍然是危險的,SQL 注入向量仍然是危險的,shell 指令仍然是危險的。百分比編碼不是輸入驗證,不是清理,也不是安全邊界。它只是表示格式。
解碼恢復原始位元組 - 因此每個下游上下文再次看到原始值
特定於上下文的轉義才是真正的保護所在。 HTML 上下文需要實體:小於變為 <,大於變為 >,引號變為 ",& 變為 &。SQL 上下文需要參數化查詢,將結構與資料分開,防止攻擊者突破。Shell 上下文需要參數數組,完全避免分詞和通配。
每個情境都有不同的危險特徵和不同的逃逸規則。 HTML 實體在 SQL 查詢中是無害的,但對於那裡的保護毫無用處。反斜線可以防止某些資料庫中的 SQL 注入,但不能防止其他資料庫中的 SQL 注入。 Shell 轉義取決於引用風格。開發人員在選擇如何處理資料之前必須了解目的地。
上下文特定的轉義 — 用於標記的 HTML 實體、用於 SQL 的參數化查詢、用於 shell 的參數數組
工作範例:以下從連結到日誌到頁面的有效負載揭示了編碼和轉義必鬚髮生的位置。連結包含編碼的 XSS 有效負載作為查詢參數。伺服器收到的資料仍然編碼在 HTTP 請求正文中。應用程式解碼查詢參數以將其顯示在頁面中。如果沒有輸出轉義,瀏覽器會將有效負載呈現為 HTML 並執行它。
如果相同的參數記錄到檔案中,則日誌條目清楚地包含解碼的有效負載。第二個應用程式讀取日誌,再次解碼,將其插入 HTML 頁面而不轉義。有效負載第二次執行。在每一步中,上下文決定什麼是安全的。 URL 解碼是安全的。檔案存儲是安全的。但不轉義的 HTML 輸出是致命的。
工作範例:追蹤從連結到日誌到頁面的一個有效負載 - 在哪裡編碼、在哪裡解碼、在哪裡必須轉義
編碼作為過濾器規避工具說明了為什麼攻擊者會進行雙重編碼並顯著混合十六進位大小寫。如果防火牆尋找 img 標籤,攻擊者會發送 %3Cimg 並希望應用程式解碼一次,但防火牆不會。如果驗證拒絕 %3Cimg 但允許不同的情況,則相同的位元組解碼為相同的負載。依賴模式匹配編碼輸入的安全性很脆弱。
解碼必須準確且絕對可預測。規範形式(小寫十六進制,已知編碼)允許一致的策略,但不能解決根本問題。唯一可靠的方法是允許在必要時進行解碼,並在使用前立即應用上下文特定的輸出轉義。解碼從來都不是安全的;僅是傳輸所必需的。
編碼作為過濾器規避工具 - 為什麼攻擊者雙重編碼並混合十六進制大小寫,以及為什麼解碼必須準確
完整的 XSS 防禦需要完全理解資料流、每個步驟所經過的上下文、以及轉義每個上下文所需的內容。 URL 編碼是一小部分:僅在傳輸過程中保留結構。但一件作品本身並不是防禦。許多開發人員將編碼與清理混為一談,因為兩者都涉及替換字符,但服務於完全不同的重要工作。
Web 應用程式防火牆可以偵測請求負載中的模式,但編碼很容易逃避簡單的模式匹配技術。 WAF 調整非常複雜,超出了 URL 編碼的範圍。可靠的防禦是應用程式程式碼中的輸出轉義,與對您的特定上下文和要求有意義的輸入驗證相結合。
這不包括什麼 - 完整的 XSS 防禦指南或 Web 應用程式防火牆調整
完整的 XSS 防禦需要完全理解資料流、每個步驟所經過的上下文、整個應用程式中每個上下文需要什麼轉義。 URL 編碼是一小部分:僅在傳輸過程中保留結構。但一件作品本身並不是防禦。許多開發人員將編碼與清理混為一談,因為兩者都涉及替換字符,但在整個開發過程中服務於完全不同的重要工作。
端對端測試有效負載,以了解整個過程中編碼和轉義真正重要的地方。將 %3Cimg%20src%3Dx%20onerror%3Dalert%281%29%3E 貼到 URL 解碼器中,並觀察它變成看起來像標記的字串。然後將結果貼到 HTML 實體轉義器中,看看如何變成安全文字。兩個工具使圖層清晰可見。
重點:對 URL 進行編碼,對輸出進行轉義 — URL 編碼器和解碼器以及 HTML 實體轉義器如何在一個產品中並排放置以完成兩項不同的工作
重點是,編碼和轉義絕對是不同層的獨立關注點。 URL 編碼僅保護傳輸的結構。輸出轉義可以保護渲染的內容。正確編碼的值在到達 HTML 時仍需要輸出轉義。正確轉義的字串如果不放入 URL,則永遠不需要 URL 編碼。
真正在右邊應用右防禦。不要依賴 URL 編碼來阻止 XSS 攻擊。不要依賴 HTML 轉義來保留 URL 結構。了解您的資料流並在每個步驟中應用適當的轉換。 URL 編碼器可協助您了解編碼的作用;然後使用 HTML 實體轉義器進行輸出步驟。