開發者工具 · HTML 實體轉義器
在沒有innerHTML的情況下解碼HTML實體:尋找表解碼器的工作原理
· 工作原理
html 安全 編碼
透過指派給innerHTML來解碼實體的流行技巧是透過HTML解析器運行您的輸入,這正是您不想要的。這篇文章解釋了更安全的基於表的方法以及它如何處理命名、十進制和十六進制引用。
執行 <img onerror> 的解碼器——一個具體的例子,其中「解碼它」變成了腳本執行
常見的單行 element.innerHTML = 輸入的作用不只是解碼 &。如果輸入也包含 <img src=x onerror=...>,則瀏覽器將建立一個影像元素和一個事件處理程序屬性。根據該節點的附加和載入方式,這可以將格式化捷徑轉換為腳本執行。當唯一的工作是解析字元引用而不是解析為 DOM 樹時,貼上的類似 HTML 的字串應該保留資料。
innerHTML 實際上對字串做了什麼——解析、元素創建和事件處理程序屬性,而不僅僅是實體替換
innerHTML 呼叫 HTML 解析器:標籤成為節點,屬性取得瀏覽器意義,稍後讀取的 textContent 會從結果中移除標記。您打算保留為文字輸入的 <strong> 標記可能會隨著文字格式而消失。分離的元件並不能保證一般的安全性;程式碼經常會重新插入該子樹或在其他地方使用產生的 HTML。如果您需要顯示不受信任的輸入,請僅在您故意選擇呈現 HTML 時指派 textContent 並進行清理。
找出表格方法 - &name;, &#NNN; 的正規表示式和 &#xHHH;,以及從名字到角色的映射
ToolAcre 的解碼器使用有界正規表示式來尋找 &name;、{ 或 { 形式的參考。命名參考在實用的顯式表格中查找,包括 amp、lt、gt、引號和常見排版。未知的名字是寫下來的,而不是猜測的。這種方法不會建立任何元素,也不呼叫 HTML 解析器;它只是替換字串中已識別的子字串。該表特意是一個子集,而不是所有 HTML 命名字元參考。
處理數字引用 - 解析十進制和十六進位代碼點並將它們轉換為字串,包括星體字符
對於數字引用,解析 &# 後的十進位或 &#x 後的十六進制,然後使用 String.fromCodePoint 將數字代碼點轉換為字元。諸如 0x1F600 之類的星體值會產生一個表情符號,而不是兩個獨立的可列印字元。此實作也像瀏覽器一樣會對應歷史 Windows-1252 控制範圍值;零、代理程式碼點和 U+10FFFF 以上的值成為取代字元。這種明確的錯誤處理可以防止無效的數字導致解碼器崩潰。
工作範例:解碼混合 &、© 和 😀 的字串 - 從表格或數字解析的每個匹配
解碼文字輸入 &、© 和 😀:第一個引用透過命名表對應到 &,十進位 169 變成 ©,十六進位 1F600 變成 😀。在它們旁邊包含一個原始的 <img onerror="alert(1)"> 。解碼器將看起來像標籤的序列作為普通字串字元返回;它不創建圖像或執行事件。稍後將結果放入實際頁面時,請使用安全文字接收器,而不是取得解碼後的字串並將其指派回innerHTML。
表格方法不會做什麼——遺留的無分號引用和解析器錯誤恢復怪癖,除非故意實現
查找方法有意不重現 HTML 解析器的遺留無分號復原規則。不含分號的 © 可能保持不變。固定命名表也省略了兩千多個 HTML5 命名引用中的許多內容。對於小型可預測解碼器來說,這些限制是誠實的權衡。僅接受明確終止引用可以避免將包含&符號的任意散文視為標記。如果完整的瀏覽器相容性是必要的,請檢查該工具記錄的支援名稱。
這不包括什麼——清理你打算渲染的 HTML,這是一個不同的問題
解碼引用並不會淨化 HTML 以供顯示。如果解碼後的文字包含 <script> 序列,那麼如果應用程式的不同部分稍後將其插入,則仍然很危險。 HTML 屬性、JavaScript 字串和 URL 等上下文都需要自己的輸出編碼和策略。 ToolAcre 返回文字;它不能使未來不安全的水槽變得安全。
重點:將輸入視為資料 — HTML 實體轉義器如何使用查找表而不是 HTML 解析器進行解碼,因此您的輸入仍為文字
將輸入視為資料。 HTML 實體轉義器使用表格和程式碼點算術進行解碼,而不是使用 insideHTML 技巧,因此看起來標記的有效負載在工具中仍然是惰性字元。嘗試這三個引用,然後檢查解碼後的文字以及您接下來計劃如何使用它:如果您將其重新解析為 HTML,則安全邊界將會遺失。