清理不受信HTML(防止XSS攻击)
问题
在网站上允许不受信的用户提供HTML作为输出(e.g. 提交评论)。需要清理该HTML来避免跨站点脚本(XSS)攻击。
解决方案
使用jsoup提供的HTML Cleanner
和一个指定Whitelist
白名单的配置。
String unsafe = "<p><a href='http://example.com/' onclick='stealCookies()'>Link</a></p>";
String safe = Jsoup.clean(unsafe, Whitelist.basic());
// now: <p><a href="http://example.com/" rel="nofollow">Link</a></p>
描述
- 跨站点脚本攻击对网站和用户造成极大影响。许多网站不允许在用户提交的内容中使用HTML来避免XSS攻击:它们强制只执行纯文本,或者使用另一种标记语法,比如wiki-text或Markdown。对于用户来说,这些解决方案很少是最优的,因为它们降低了表达能力,并迫使用户学习新的语法。
- 更好的解决方案可能是使用富文本所见即所得的编辑器(如CKEditor或TinyMCE)。它们输出HTML,并允许用户可视化工作。但是,它们的验证是在客户端完成的:您需要应用服务器端验证来清理输入并确保HTML可以安全地放置在网站上。否则,攻击者可以避免客户端Javascript验证将不安全的HMTL直接注入网站。
- jsoup白名单过滤器通过解析输入HTML(在安全的沙盒环境中),然后遍历解析树,只允许已知安全的标记和属性(和值),清理过后进入输出。
它不使用正则表达式。 - jsoup提供了一系列白名单配置来满足绝大多数的需求,如果有必要,它们可以修改,但要小心使用。
Cleaner
不仅可以避免XSS欺诈,还可以限制用户可以提供的元素的范围:允许使用文本a
、strong
元素,但不能使用结构化div
或table
元素。