python做web開發當今已經逐漸成為主流之一,但相關的一些第三方模組和庫還沒有php和node.js多。
比如XSS過濾組件,PHP下有著名的“HTML Purifier”(http://htmlpurifier.org/ ),還有非著名過濾組件“XssHtml”(http://phith0n.github.io/XssHtml )
python的pip下也可以安裝一款名為“html-purifier”的庫,但此purifier和php下的就大不相同了。這個庫負責將html中,白名單以外的標籤和屬性過濾掉。
注意,他並不是過濾XSS的,只是過濾不在白名單內的標籤和屬性。也就是說,類似等javascript是不會被過濾的。
所以我只好自己開發了一個python xss filter,用在自己以後做的python項目中。
說一下具體實現原理。
一、解析HTML
解析HTML,使用的是python內建的HTMLParser類。在python2中,名字叫HTMLParser,在python3中叫html.parser。
使用HTMLParser,需要自己的類繼承HTMLParser,並實現其中的handle_starttag、handle_startendtag、handle_endtag、handle_data等方法。
如handle_starttag方法,是在進入一個標籤的時候被調用的。我們就可以在實現這個方法的時候,就可以獲得此時正在處理的標籤tag,和所有屬性attrs。
我們就可以檢查tag、attrs是否在白名單中,並對其中特殊的一些標籤和屬性做特殊處理,如下:
二、連結特殊處理
有些屬性是可以用javascript偽協議來執行javascript代碼的,如a的href,embed的src,所以需要對其進行特殊處理:判斷是否以http|https|ftp://開頭,如果不是則強制在前面加上http://
通過這個方式,對抗潛在的XSS注入。
三、embed特殊處理
embed是嵌入swf等媒體檔案的標籤,理論上有時候我們的富文字編輯器是允許插入flash的。但我們需要保證flash內不能執行任意javascript代碼,也不能讓他發出一些HTTP請求(容易造成CSRF攻擊)。
所以強制設定embed標籤的allowscriptaccess=never,allownetworking=none:
四、拼接標籤和屬性的時候,防止雙引號越出,成為新標籤
我曾經在Roundcube Webmail中找到一個XSS漏洞(CVE-2015-1433),導致原因就是因為白名單檢測完畢後再拼接html標籤和屬性的時候沒有過濾雙引號,導致屬性值越出,變成一個新的屬性名稱,導致XSS。
所以我這裡使用self.__htmlspecialchars處理屬性值,防止越出:
最後,這個模組使用也比較方便,最簡單的demo如下:
import pxfilter
parser = pxfilter.XssHtml()
parser.feed('')
parser.close()
html = parser.getHtml()
print html
再根據源碼中的說明進行修改即可。github項目地址:https://github.com/phith0n/python-xss-filter
自己用web.py搭了個demo,歡迎測試、提交issues:http://python-xss-filter.leavesongs.com/ ,功能上、安全上都還需要大家給些建議。