跨站腳本攻擊(XSS)已經不是什麼新鮮的話題了,甚至不少大公司也爲此吃盡苦頭。最簡單直接的防範方法,就是不容許任何html標籤輸入,對用戶輸入進行編碼(htmlencode)。
可是若是想用戶輸入支持一些格式,怎麼辦?一種辦法就是不少論壇採用的BB Code的方法。使用特定的標籤代替一些格式。好比:[B]表示粗體,等等。可是,BB Code這種形式並不被普遍接受,它的表現力實在太差了,並且並非標準格式。
爲了讓用戶的輸入更具表現力,涌現了大量的Html編輯器控件,著名的有FCKEditor,FreeTextBox,Rich TextBox,Cute Editor,TinyMCE等等。好比,博客園的後臺發隨筆就支持Cute Editor和TinyMCE,我我的比較喜歡Cute Editor,功能強大,性能不錯,並且容易定製。
使用這些Html編輯器控件的潛在危險,是用戶可能會輸入一些危險字符,注入到網站中,造成XSS攻擊。一個最簡單的輸入就是:javascript
<
javascript
>
alert(
'
xss
'
)
<
/
javascript>
如何防止呢?大體思路有三種:
1. 正則表達式的白名單過濾機制。
2. 正則表達式的黑名單替換機制。
3. 經過DOM對象過濾白名單和黑名單的標籤。
下面這個地址列舉了不少這樣的過濾方法:
http://refactormycode.com/codes/333-sanitize-html
不過,我試了上面連接裏的一些方法,並非很好用。有一個更簡單好用的東西,就是
AntiXSS,由微軟推出的用於防止XSS攻擊的一個類庫。它的實現原理也是使用白名單機制,不過這個白名單對咱們來講是一個黑盒,我用reflector粗略看了一下,也沒找到所謂的白名單在哪裏。不過,這個庫確實很好用。
一個MSDN裏圖文並茂的使用說明:
http://msdn.microsoft.com/en-us/library/aa973813.aspx
其實我用的很簡單,就是
AntiXss.GetSafeHtmlFragment(html)方法,這個方法會替換掉html裏的危險字符。好比:
var html
=
"
<a href=\
"
#\
"
onclick=\
"
alert();\
"
>aaaaaaaaa</a>javascript<P><IMG SRC=javascript:alert('XSS')><javascript>alert('a')</javascript><IMG src=\
"
abc.jpg\
"
><IMG><P>Test</P>
"
;
string
safeHtml
=
AntiXss.GetSafeHtmlFragment
(html);
Console.WriteLine(safeHtml);
上面的危險內容被成功替換,返回的內容是:
<
a
href
=""
>
aaaaaaaaa
</
a
>
javascript
<
p
><
img
src
=""
>
alert('a')
<
img
src
="abc.jpg"
><
img
></
p
>
<
p
>
Test
</
p
>
嗯,很是安全。而後,又有一個疑問了,是應該將用戶的輸入過濾以後寫入數據庫呢?仍是在輸出界面顯示的時候進行過濾?其實,一般來說,在輸出界面顯示的時候進行過濾就夠了,將用戶輸入過濾後寫入數據庫不是很必要,由於即便這樣也沒法保證數據庫中沒有危險的數據。固然,上個雙保險也沒有什麼很差的。html