我正在尝试编写一个安全且轻量级的基于白名单的HTML净化器,它将使用DOMDocument。为了避免不必要的复杂性,我愿意做出以下妥协:
script
和style
标签一起被剥离body
标记的子节点我一直在阅读有关XSS攻击和预防的很多内容,我希望我不是太天真(如果我,请让我知道!)假设如果我遵循上面提到的所有规则,我将免于XSS。
问题是除了default Javascript event attributes之外,我不确定其他标签和属性(在任何[X] HTML版本和/或浏览器版本/实现中)可以触发Javascript事件:
onAbort
onBlur
onChange
onClick
onDblClick
onDragDrop
onError
onFocus
onKeyDown
onKeyPress
onKeyUp
onLoad
onMouseDown
onMouseMove
onMouseOut
onMouseOver
onMouseUp
onMove
onReset
onResize
onSelect
onSubmit
onUnload
是否有任何其他非默认或专有事件属性可以触发Javascript(或VBScript等)事件或代码执行?我可以考虑href
,style
和action
,例如:
<a href="javascript:alert(document.location);">XSS</a> // or
<b style="width: expression(alert(document.location));">XSS</b> // or
<form action="javascript:alert(document.location);"><input type="submit" /></form>
我可能会删除HTML标记中的所有style
属性,action
和href
属性会带来更大的挑战,但我认为以下代码足以确保其价值是一个相对或绝对的URL,而不是一些讨厌的Javascript代码:
$value = $attribute->value;
if ((strpos($value, ':') !== false) && (preg_match('~^(?:(?:s?f|ht)tps?|mailto):~i', $value) == 0))
{
$node->removeAttributeNode($attribute);
}
所以,我的两个显而易见的问题是:
经过大量的测试,思考和研究后,我提出了following (rather simple) implementation,它似乎对我可以投射的任何XSS攻击矢量免疫。
我非常感谢您所有有价值的答案,谢谢。
答案 0 :(得分:10)
您提到href
和action
,因为可以显示javascript:
个网址,但您在其他一些网址加载属性中缺少src
属性。
Line 399 of the OWASP Java HTMLPolicyBuilder是白名单HTML清理程序中URL属性的定义。
private static final Set<String> URL_ATTRIBUTE_NAMES = ImmutableSet.of( "action", "archive", "background", "cite", "classid", "codebase", "data", "dsync", "formaction", "href", "icon", "longdesc", "manifest", "poster", "profile", "src", "usemap");
HTML5 Index包含属性类型的摘要。它没有提及像<input type=URL value=...>
这样的条件事项,但是如果你扫描valid URL和朋友的列表,你应该对HTML5添加的内容有所了解。具有%URI
类型的HTML 4 attributes集也是提供信息的。
您的协议白名单与OWASP sanitizer非常相似。添加ftp
和sftp
看起来非常无害。
HTML元素和属性的安全相关模式信息的良好来源是Caja Caja JSON whitelists使用的JS HTML sanitizer。
您打算如何渲染生成的DOM?如果您不小心,那么即使您删除了所有<script>
元素,攻击者也可能会获得一个错误的渲染器来生成浏览器解释为包含<script>
元素的内容。考虑不包含脚本元素的有效HTML。
<textarea></textarea><script>alert(1337)</script></textarea>
有错误的渲染器可能会将其内容输出为:
<textarea></textarea><script>alert(1337)</script></textarea>
包含脚本元素。
(完全披露:我写了上面提到的两种HTML消毒剂的大块。)
答案 1 :(得分:4)
嘉鲁达已经给出了我认为的“正确”答案,他的链接非常有用,但是他打败了我!#/ p>
我的回答只是为了加强。
在html和ecmascript规范中增加功能的这个时代,避免脚本注入和html中的其他此类漏洞变得越来越困难。每增加一次,就会引入一整个可能的注射世界。这与以下事实相结合:不同的浏览器可能对如何实现这些规范有不同的想法,因此您可能会遇到更多可能的漏洞。
查看html 5
引入的简短矢量列表最好的解决方案是选择允许的内容而不是拒绝的内容。更容易说“这些标签和那些给定标签的属性是允许的。其他所有东西都会相应地消毒或抛弃。”
对我来说,编制清单并说“好吧,你走了,这是非常不负责任的:这里是你错过的所有注射媒介的清单。你可以轻松入睡。”实际上,可能有许多注射载体甚至不为黑帽子或白帽子所知。正如ha.ckers网站所述,脚本注入实际上只受到思想的限制。
我想至少回答一下你的具体问题,所以这里有一些来自你的黑名单的明显遗漏:
img
src
属性。我认为重要的是要注意src
是其他元素的有效属性,可能有害。 img
也dynsrc
和lowsrc
,甚至更多。type
和language
属性CDATA
除了html评论之外。head
内的html
和body
元素以及大多数head
- 只有body
内的元素,所以这可能无济于事。frame
s和iframe
s embed
,可能还有object
和applet
顺便说一下,我确定这没关系,但是camelCased属性是无效的xhtml,应该更低。我相信这不会影响你。
答案 2 :(得分:2)
您可能需要查看这两个链接以获取更多参考:
http://adamcecc.blogspot.com/2011/01/javascript.html(这仅适用于“过滤后”输入会在页面上的脚本标记之间发现的情况)
http://ha.ckers.org/xss.html(其中列出了许多特定于浏览器的事件触发器)
我已经使用了HTML Purifier,正如你所做的那样,因为这个原因也与wysiwyg-editor结合使用。我所做的不同的是使用一个非常严格的白名单,其中包含几个基本的标记标记和属性,并在需要时扩展它。这可以防止你受到非常模糊的向量的攻击(比如上面的第一个链接),你可以逐个深入挖掘新需要的标签/属性。
只需2美分..
答案 3 :(得分:0)
不要忘记HTML5 JavaScript事件处理程序
http://www.w3schools.com/html5/html5_ref_eventattributes.asp