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

Ali*_*xel 21 html javascript php security xss

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

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

我一直在阅读关于XSS攻击和预防的很多内容,我希望我不是太天真(如果我,请让我知道!)假设如果我遵循上面提到的所有规则,我将会从XSS安全.

问题是除了默认的Javascript事件属性之外,我不确定其他标签和属性(在任何[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>
Run Code Online (Sandbox Code Playgroud)

我可能只是删除styleHTML标记中的任何属性,action并且href属性构成了更大的挑战,但我认为以下代码足以确保它们的值是相对或绝对URL而不是一些讨厌的Javascript代码:

$value = $attribute->value;

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

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

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

经过大量的测试,思考和研究后,我提出了以下(相当简单的)实现,它似乎对我可以抛出的任何XSS攻击向量免疫.

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

Mik*_*uel 10

你提到hrefaction作为地方javascript:的URL可以显示,但你错过了src一堆其他的URL加载属性之间的属性.

OWASP Java HTMLPolicyBuilder的第399行是白名单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");
Run Code Online (Sandbox Code Playgroud)

HTML5指数包含的属性类型的摘要.它没有提到一些有条件的事情,<input type=URL value=...>但如果你扫描该列表中的有效URL和朋友,你应该对HTML5添加的内容有所了解.具有类型的HTML 4属性%URI也是提供信息的.

您的协议白名单看起来非常类似于OWASP清洁剂.添加ftp并且sftp看起来非常无害.

HTML元素和属性的安全相关模式信息的良好来源是Caja JS HTML清理程序使用的Caja JSON白名单.

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

<textarea><&#47;textarea><script>alert(1337)</script></textarea>
Run Code Online (Sandbox Code Playgroud)

有错误的渲染器可能会将其内容输出为:

<textarea></textarea><script>alert(1337)</script></textarea>
Run Code Online (Sandbox Code Playgroud)

它包含一个脚本元素.

(完全披露:我写了上面提到的两种HTML消毒剂的块.)


Exp*_*lls 5

Garuda 已经给出了我认为“正确”的答案,他的链接非常有用,但他抢先了我!

我给出我的答案只是为了强化。

在当今 html 和 ecmascript 规范中功能不断增加的时代,避免 html 中的脚本注入和其他此类漏洞变得越来越困难。每添加一个新的内容,都会引入一系列可能的注射方式。再加上不同的浏览器对于如何实现这些规范可能有不同的想法,因此您可能会遇到更多可能的漏洞。

看一下html 5引入的向量简短列表

最好的解决方案是选择你允许的而不是你拒绝的。说“这些标签和这些给定标签的属性是允许的。其他所有内容都会相应地进行清理或丢弃”要容易得多。

对我来说,编制一份清单并说“好吧,给你:这是你错过的所有注射向量的清单。你可以高枕无忧了”,这是非常不负责任的。事实上,可能有很多黑帽或白帽都不知道的注入向量。正如 ha.ckers 网站所述,脚本注入实际上仅受思维限制。

我想至少回答一下您的具体问题,因此以下是您的黑名单中的一些明显遗漏:

  • img src属性。我认为重要的是要注意这src是其他元素的有效属性,并且可能具有潜在的危害。 img还有dynsrclowsrc甚至更多。
  • typelanguage属性
  • CDATA除了 html 注释之外。
  • 输入值清理不当。这可能不是问题,具体取决于您的 html 解析的严格程度。
  • 任何不明确的特殊字符。在我看来,即使是明确的也应该被编码。
  • 属性上的引号缺失或不正确(例如严重引号)。
  • 过早关闭文本区域标签。
  • 脚本中的 UTF-8(和 7)编码字符
  • 即使您只会返回 body 标记的子节点,许多浏览器仍然会评估head, 和html内的元素body,以及head内的most-only 元素body,所以这可能不会有太大帮助。
  • 除了css表达式之外,还有背景图片表达式
  • frameiframes
  • embed可能objectapplet
  • 服务器端包括
  • PHP 标签
  • 任何其他注入(SQL 注入、可执行注入等)

顺便说一句,我确信这并不重要,但camelCased属性是无效的xhtml,应该是小写的。我确信这不会影响你。