字元編碼帶來的安全隱患——一個谷歌XSS漏洞
本文翻譯自 http://shiflett.org/blog/2005/dec/googles-xss-vulnerability
多年以前谷歌曾爆出一個XSS漏洞證明了字元編碼設定的重要性。
但直到2011年,這種漏洞還是時有發生。
一個典型的例子參見淘寶UTF7漏洞跨站注入漏洞:http://xiaohaizi.org/article/550.html
正文:
PHP 函式 htmlentities() 第三個引數聲明瞭字元的編碼:
(yukon12345:這個函式是過濾HTML特殊字元,轉化成html編碼字符集。比如’會轉化為')
<?php $html = array(); $html['username']= htmlentities($clean['username'], ENT_QUOTES, 'UTF-8'); echo"<p>Welcome back, {$html['username']}.</p>"; ?>
這個例子用了UTF-8,因此Content-Type header本來應該在伺服器或HTML文件宣告為
Content-Type:text/html; charset=UTF-8
有研究者用Watchfire 檢視到谷歌並沒有宣告文字編碼。同時他們也發現如果你用下面一個URL連結訪問(這個連結並不存在)
http://google.com/url?EVIL
你會看到一個返回頁面:
Forbidden
Your client doesnot have permission to get URL /url?EVIL from this server.
但谷歌並沒有很好的處理含utf7編碼的惡意提交。因為上面那個php過濾函式針對的是UTF-8。
同時由於谷歌沒有在返回頁面charset裡宣告編碼方式,
如果使用IE瀏覽器,它會自動判斷前4096位元組的字元,找到UTF7編碼的字元的話,IE將forbidden頁面以UTF-7方式編碼呈現。這樣就繞過了谷歌的防XSS措施,導致敏感字元沒有被過濾。
這個故事說明,你必須確保你轉碼程式和資料傳送系統的編碼一致性。
換句話說,
使用htmlentities()時保持編碼一致性, 或者使用 mysql_real_escape_string() (取決於你的選擇)
谷歌已經修復了這個漏洞。
yukon12345:外國人的找錯方式真的很特別。另外這篇文章是2005年的了,翻譯一下是因為我之後翻譯的一本書裡有提及字元編碼的安全性。