2010-09-10 60 views
11

我試圖從客戶端進行消毒和XSS驗證一些HTML輸入。我用美麗的湯來使用Python 2.6。我解析輸入,將所有標籤和屬性不在白名單中,然後將該樹轉換回字符串。如何使美麗的湯輸出HTML實體?

但是......

>>> unicode(BeautifulSoup('text < text')) 
u'text < text' 

這並不像有效的HTML給我。並與我的標籤剝離器,它開闢了道路種種污穢:

>>> print BeautifulSoup('<<script></script>script>alert("xss")<<script></script>script>').prettify() 
< 
<script> 
</script> 
script>alert("xss")< 
<script> 
</script> 
script> 

<script></script>對將被刪除,剩下的就是不僅XSS攻擊,但即使是有效的HTML也是如此。

顯而易見的解決方案是將所有<個字符替換爲&lt;,即在解析後,發現它們不屬於標記(以及類似的>&'")。但Beautiful Soup documentation只提到實體的解析,而不是它們的產生。當然,我可以在所有的NavigableString節點上運行一個替換,但由於我可能會錯過某些東西,我寧願讓一些久經考驗的代碼來完成這項工作。

爲什麼不美麗的湯默認冒險<(和其他魔法字符),我該如何做到這一點?


N.B.我也看過lxml.html.clean。它似乎在黑名單的基礎上工作,而不是白名單,所以它對我來說似乎不是很安全。標籤可以列入白名單,但屬性不能,並且它允許太多屬性(例如tabindex)。此外,它在輸入<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>上給出AssertionError。不好。

其他清理HTML方法的建議也非常受歡迎。我並不是世界上唯一試圖這樣做的人,但似乎沒有標準的解決方案。

+0

'text Gumbo 2010-09-10 13:03:21

+0

哦,對。無論如何,它使用'text '示例做同樣的事情。 – Thomas 2010-09-10 13:41:00

回答

2

lxml.html.clean.Cleaner類允許您提供帶有allow_tags參數的標記白名單,並使用feedparser中的預計算屬性白名單和safe_attrs_only參數。而且lxml在序列化時可以正確處理實體。

+0

就像我在原始問題中寫的一樣,它不允許我更改屬性列表。例如,'tabindex'可以使網站以意想不到的方式行事,並且在一些想象中,像charset這樣的各種編碼屬性也可以用於惡意目的,而它們很少(如果有的話)有用。我寧願只允許實際有用(和使用)的屬性。 – Thomas 2010-09-10 12:10:53

+0

它們位於Feedparser接受的屬性列表中,它非常偏執。如果你更偏執狂,你可以將'lxml.html.defs.safe_attrs'設置爲你認爲安全的屬性。或者,如果不是完全沒有貨架,您可以重新使用'feedparser._HTMLSanitizer'類,修改它以適應您想要允許的屬性。 – llasram 2010-09-10 12:17:42

+2

我不喜歡那個清單。 '

'元素就在它上面。哦,我剛剛在'lxml/html/defs.py'中發現了一個拼寫錯誤:'marque',而不是'marquee',它仍然存在於svn版本中。我報告過一個錯誤。沒有什麼大不了的,但它並沒有幫助建立信心... – Thomas 2010-09-10 12:28:22