XSS - 哪些HTML标记和属性可以触发Javascript事件?

时间:2011-08-07 21:54:49

标签: php javascript html security xss

我正在尝试编写一个安全且轻量级的基于白名单的HTML净化器,它将使用DOMDocument。为了避免不必要的复杂性,我愿意做出以下妥协:

  • HTML评论已删除
  • scriptstyle标签一起被剥离
  • 仅返回body标记的子节点
  • 可以触发Javascript事件的所有HTML属性都将被验证或删除

我一直在阅读有关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等)事件或代码执行?我可以考虑hrefstyleaction,例如:

<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属性,actionhref属性会带来更大的挑战,但我认为以下代码足以确保其价值是一个相对或绝对的URL,而不是一些讨厌的Javascript代码:

$value = $attribute->value;

if ((strpos($value, ':') !== false) && (preg_match('~^(?:(?:s?f|ht)tps?|mailto):~i', $value) == 0))
{
    $node->removeAttributeNode($attribute);
}

所以,我的两个显而易见的问题是:

  1. 我是否遗漏了可以触发事件的任何标签或属性?
  2. 是否有这些规则未涵盖的攻击媒介?

  3. 经过大量的测试,思考和研究后,我提出了following (rather simple) implementation,它似乎对我可以投射的任何XSS攻击矢量免疫。

    我非常感谢您所有有价值的答案,谢谢。

4 个答案:

答案 0 :(得分:10)

您提到hrefaction,因为可以显示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非常相似。添加ftpsftp看起来非常无害。

HTML元素和属性的安全相关模式信息的良好来源是Caja Caja JSON whitelists使用的JS HTML sanitizer

您打算如何渲染生成的DOM?如果您不小心,那么即使您删除了所有<script>元素,攻击者也可能会获得一个错误的渲染器来生成浏览器解释为包含<script>元素的内容。考虑不包含脚本元素的有效HTML。

<textarea><&#47;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是其他元素的有效属性,可能有害。 imgdynsrclowsrc,甚至更多。
  • typelanguage属性
  • CDATA除了html评论之外。
  • 未正确清理输入值。根据你的html解析的严格程度,这可能不是问题。
  • 任何暧昧的特殊人物。在我看来,即使是明确的也应该编码。
  • 缺少或不正确的属性引号(例如严重引号)。
  • textarea标签过早关闭。
  • 脚本中的UTF-8(和7)编码字符
  • 即使您只返回body标记的子节点,许多浏览器仍会评估head内的htmlbody元素以及大多数head - 只有body内的元素,所以这可能无济于事。
  • 除了css表达式,背景图像表达式
  • frame s和iframe s
  • embed,可能还有objectapplet
  • 服务器端包括
  • PHP标签
  • 任何其他注入(SQL注入,可执行注入等)

顺便说一下,我确定这没关系,但是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