幾種極其隱蔽的XSS注入的防護

原文地址:http://blogread.cn/it/article.php?id=5733&f=sinat

XSS注入的本質就是: 某網頁中根據用戶的輸入, 不期待地生成了可執行的js代碼, 並且js得到了瀏覽器的執行. 意思是說, 發給瀏覽器的字符串中, 包含了一段非法的js代碼, 而這段代碼跟用戶的輸入有關.

常見的XSS注入防護, 可以通過簡單的 htmlspecialchars(轉義HTML特殊字符), strip_tags(清除HTML標籤) 來解決, 但是, 還有一些隱蔽的XSS注入不能通過這兩個方法來解決, 而且, 有時業務需要不允許清除HTML標籤和特殊字符. 下面列舉幾種隱蔽的XSS注入方法:

IE6/7 UTF7 XSS 漏洞攻擊

隱蔽指數: 5
傷害指數: 5

這個漏洞非常隱蔽, 因爲它讓出現漏洞的網頁看起來只有英文字母(ASCII字符), 並沒有非法字符, htmlspecialchars 和 strip_tags 函數對這種攻擊沒有作用. 不過, 這個攻擊只對 IE6/IE7 起作用, 從 IE8 起微軟已經修復了. 你可以把下面這段代碼保存到一個文本文件中(前面不要有空格和換行), 然後用 IE6 打開試試(沒有惡意代碼, 只是一個演示):

+/v8 +ADw-script+AD4-alert(document.location)+ADw-/script+AD4-

最容易中招的就是 JSONP 的應用了, 解決方法是把非字母和數字下劃線的字符全部過濾掉. 還有一種方法是在網頁開始輸出空格或者換行, 這樣, UTF7-XSS 就不能起作用了.

因爲只對非常老版本的 IE6/IE7 造成傷害, 對 Firefox/Chrome 沒有傷害, 所以傷害指數只能給 4 顆星.

參考資料: UTF7-XSS

不正確地拼接 JavaScript/JSON 代碼段

隱蔽指數: 5
傷害指數: 5

Web 前端程序員經常在 PHP 代碼或者某些模板語言中, 動態地生成一些 JavaScript 代碼片段, 例如最常見的:

var a = '<?php echo htmlspecialchars($name); ?>';

不想, $name 是通過用戶輸入的, 當用戶輸入 a’; alert(1); 時, 就形成了非法的 JavaScript 代碼, 也就是 XSS 注入了.

在解決問題之前, 我們要思考問題的本質是什麼? 本質在於程序員可以用字符串來控制整個世界, 卻沒有用正確的方法來生成正確的字符串, 而是採用了功能強大且原始的”手工字符串拼接”.

只需要把上面的代碼改成:

var a = <?php echo json_encode($name); ?>;

去掉單引號, 利用 PHP 的 json_encode() 函數來生成表示字符串的字符串. 這樣做是因爲, 最好用 json_encode() 函數來生成所有的 JSON 串, 而不要試圖自己去拼接. 程序員總是犯這樣的錯誤: 自己去解析 HTTP 報文, 而不是用現成的成熟的庫來解析. 用 json_encode() 的好處還在於, 即使業務要求”我要保留單引號”時, XSS注入也可以避免.

隱蔽指數最高級, 傷害所有的通用瀏覽器. 這種 XSS 注入方式具有非常重要的參考意義.

最後, 根據工作中的經驗, 以及我自己和別人犯過的錯, 我總結出一個定理: 沒有一勞永逸的單一方法可以解決所有 XSS 注入問題.

有用的經驗:

  • 輸出 HTML 代碼時 htmlspecialchars
  • 輸出 JavaScript 代碼時 json_encode
  • 輸入過濾應該用於解決業務限制, 而不是用於解決 XSS 注入(與嚴進寬出的原則相悖, 所以本條值得討論)

討論:

上文提到的經驗第3條, 是一種”寬進嚴出”的原則, 和”嚴進寬出”原則是相悖的. 其實, 我認爲不應該把”嚴進寬出”作爲一條僞真理, 好像除了它其它的說法都不對了似的. “寬進嚴出”和”嚴進寬出”應該具有完全相等的地位, 根據實現的成本進行取捨.

例如, 用戶的名字可以採用”嚴進寬出”原則, 不允許用戶填寫單引號, 大於號小於號等. 但是用戶的簽名呢? 難道就不能填單引號? 如果要走極端, 想找出一種銀彈, 那麼我能想到的就是對所有的輸入一律進行 htmlspecialchars 和 json_encode(且不說解決不了 utf7-xss).

其實, XSS 注入的解決應該是和輸出端相關的. 當需要輸出到文本文件時, 過濾和轉義都是無必要的. 當輸出到 HTML 渲染引擎時, json_encode 是無必要的. 當輸出到 JS 引擎時, htmlspecialchars 是無必要的.

發佈了18 篇原創文章 · 獲贊 7 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章