捕获XSS(跨站点脚本)攻击的最佳正则表达式(在Java中)?
Jeff实际上在Sanitize HTML中发布了有关此内容的文章。但是他的例子在Cand中,我实际上对Java版本更感兴趣。有没有人有更好的Java版本?他的例子足够好,可以直接从Cto Java转换吗?
[更新]我悬赏这个问题,因为当我问这个问题时,SO并不像今天(*)那样受欢迎。至于与安全相关的任何事物,研究它的人越多,它就越好!
(*)实际上,我认为它仍处于封闭测试阶段
解决方案
回答
示例中显示的正则表达式无论语言如何都可以正常工作。
那么是我们想要的正则表达式,还是将这种逻辑放在正则表达式周围的Java代码?
回答
开放Web应用程序安全性项目(OWASP)对于清理输入内容有一些建议。例如参见:
- Java目录
- 如何在Java中执行HTML实体编码
- 如何向HttpServletRequest添加验证逻辑
回答
使用jeffs代码的最大问题是@,目前尚不可用。
如果我需要,我可能会从jeffs代码中获取"原始"正则表达式并将其粘贴到
http://www.cis.upenn.edu/~matuszek/General/RegexTester/regex-tester.html
并看到需要逃生的东西逃脱然后再使用它。
考虑到此正则表达式的用法,我个人将确保自己完全了解自己在做什么,如果我不成功,那么为什么以及在复制/粘贴任何内容(如其他答案)试图为我们提供帮助之前会产生什么后果。
(对于任何复制/粘贴来说,这可能都是不错的建议)
回答
我不认为使用正则表达式是查找所有可疑代码的最佳方法。正则表达式在处理残破的HTML时特别容易被欺骗。例如,在Sanitize HTML链接中列出的正则表达式将无法删除在元素名称和属性" href"之间具有属性的所有" a"元素:
<alt =" xss注入" href =" http://www.malicous.com/bad.php">
删除恶意代码的一种更强大的方法是依靠可以处理所有HTML文档(Tidy,TagSoup等)的XML解析器,并选择要使用XPath表达式删除的元素。将HTML文档解析为DOM文档后,即可轻松安全地找到要复制的元素。使用XSLT甚至很容易做到这一点。
回答
不要使用正则表达式执行此操作。请记住,我们并不是仅仅针对有效的HTML进行保护;我们可以防止Web浏览器创建的DOM。可以诱使浏览器很容易地从无效的HTML生成有效的DOM。
例如,请参阅此混淆的XSS攻击列表。我们是否准备量身定制正则表达式以防止在IE6 / 7/8上对Yahoo和Hotmail进行这种现实世界的攻击?
<HTML><BODY> <?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time"> <?import namespace="t" implementation="#default#time2"> <t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>"> </BODY></HTML>
如何在IE6上进行这种攻击?
<TABLE BACKGROUND="javascript:alert('XSS')">
该网站未列出的攻击情况如何? Jeff的方法存在的问题是,它不是声称的白名单。正如该页面上的某人熟练地指出:
The problem with it, is that the html must be clean. There are cases where you can pass in hacked html, and it won't match it, in which case it'll return the hacked html string as it won't match anything to replace. This isn't strictly whitelisting.
我建议使用像AntiSamy这样的专用工具。它实际上是通过解析HTML,然后遍历DOM并删除所有不在可配置白名单中的内容来工作的。主要区别在于可以正常处理格式错误的HTML。
最好的部分是,它实际上对上述站点上的所有XSS攻击进行了单元测试。此外,比此API调用更容易的是:
public String toSafeHtml(String html) throws ScanException, PolicyException { Policy policy = Policy.getInstance(POLICY_FILE); AntiSamy antiSamy = new AntiSamy(); CleanResults cleanResults = antiSamy.scan(html, policy); return cleanResults.getCleanHTML().trim(); }
回答
[\ s \ w \。] *
。如果不匹配,则说明我们拥有XSS。可能是。请注意,此表达式仅允许使用字母,数字和句点。出于对XSS的担心,它避免了所有符号,甚至是有用的符号。允许&后,我们就不必担心了。仅用&替换&的所有实例是不够的。太难以置信了:P。显然,这将禁止使用许多合法的文本(我们可以将所有不匹配的字符替换为!或者其他内容),但是我认为它将杀死XSS。
仅将其解析为html并生成新的html的想法可能更好。
回答
^(\s|\w|\d|<br>)*?$
这将验证字符,数字,空格以及<br>标签。
如果我们想增加风险,可以添加更多标签,例如
^(\s|\w|\d|<br>|<ul>|<\ul>)*?$