【问题标题】:How does a browser render this inline JavaScript within an encoded tag?浏览器如何在编码标签中呈现这个内联 JavaScript?
【发布时间】:2014-05-14 14:08:04
【问题描述】:

我试图在一个教程网站上执行Reflective XSS 攻击。该网页基本上由一个带有输入字段和提交按钮的表单组成。提交表单时,输入字段的内容会显示在同一网页上。

我发现该网站将脚本标签和一些 JavaScript 方法列入黑名单以防止 XSS 攻击。所以,我决定对我的输入进行编码,然后尝试提交表单。我尝试了 2 种不同的输入,其中一种有效,另一种无效。

当我尝试时:

<body onload="&#97lert('Hi')"></body>

它成功了,并显示了一个警告框。但是,我在 HTML 标记中编码一些字符时,例如:

&#60body onload="&#97lert('Hi')"&#62&#60/body&#62

没用!它只是在网页上打印了&lt;body onload="alert('Hi')"&gt;&lt;/body&gt;

我知道浏览器在解析 HTML 文档时会执行内联 JavaScript(如果我错了,请纠正我)。但是,我无法理解为什么浏览器会针对我提到的不同输入显示不同的行为。

----------------------------------- - - - - - - - 编辑 - - - - - - - - - - - - - - - - - - ----------------------

我厌倦了没有 XSS 保护的更基本的 XSS 教程。再次:

&lt;script&gt;alert("Hi")&lt;/script&gt; -> 成功了!

&amp;#60s&amp;#99ript&amp;#62&amp;#97lert("Hi")&amp;#60/s&amp;#99ript&amp;#62 -> 没用! (在网页上打印为字符串)

所以基本上,如果我用 JavaScript 编码任何东西,它就可以工作。但是,如果我对任何 HTML 内容进行编码,它就不会在该 HTML 中执行 JavaScript!

【问题讨论】:

  • “我知道浏览器在解析 HTML 文档时会执行内联 JavaScript”,这是正确的,但您所拥有的不是内联 JavaScript,而是一个 onload 事件。 &lt;script&gt;alert("foobar!")&lt;/script&gt; 将是内联 javascript。属性确实会转换为字符串,其中 html 实体替换为实际字符,这就是页面加载警报有效的原因。
  • 啊!我明白。感谢您的澄清。
  • -1?!太宽泛?!严重地?!我不认为这个问题太宽泛了。我只需要一个关于问题中提到的案例的答案。我不是要完整的渲染过程!

标签: javascript html firefox browser xss


【解决方案1】:

我想不出合适的词来形容,所以我给你举个例子。假设我们有这个字符串:

<div>Hello World! &lt;span id="foo"&gt;Foobar&lt;/span&gt;</div>

当它被解析时,你最终会得到一个包含 text 的 div 元素:

Hello World! <span id="foo">Foobar</span>

注意,虽然文本中有一些看起来像 html 的东西,但它仍然只是文本,而不是 html。要使该文本变为 html,必须再次对其进行解析。

属性的工作方式略有不同,属性中的 html 实体第一次会被解析。

tl;博士:

如果您使用的服务正在剥离标签,那么您将无能为力,除非脚本编写不当导致字符串被解析两次。

演示:http://jsfiddle.net/W6UhU/ 注意在将 div 的内部 html 设置为等于它的内部文本后,span 变成了一个 html 元素而不是一个字符串。

【讨论】:

  • 我明白这一点。但是浏览器解析 HTML 标签encoded HTML 标签 的方式有什么不同吗?因为,未编码的 HTML 正文标签中的警报正在执行,但编码标签中的警报没有!
  • 编码的 html 标签保持原样,正如您通过执行所述测试已经发现的那样。 html标签的属性被解析,不是html标签的字符串不被解析。
  • 好的。我想这次我明白了。由于标签未编码,因此将解析其属性并执行警报方法。但是,在另一种情况下,由于标签已编码,因此标签保持原样,因此不会解析该属性。如果我错了,请纠正我。
  • 没错。如果标签不是标签,则该属性不是属性。
  • 谢谢!让我再等一段时间,等待其他人的更多解释。如果我找不到更好的答案,我会接受你的答案。
【解决方案2】:

当 HTML 页面显示 &amp;#60body 时,它的处理方式与 &amp;lt;body 相同

也就是说,它只显示编码字符,不将它们解析为 HTML。所以你不是用onload属性http://jsfiddle.net/SSfNw/1/创建一个新标签

alert(document.body.innerHTML);
// When an HTML page says &lt;body It treats it the same as if it said &lt;body  

因此,在您的情况下,您永远不会创建正文标签,只是最终移动到正文标签中的内容http://jsfiddle.net/SSfNw/2/

alert(document.body.innerHTML)
// &lt;body onload="alert('Hi')"&gt;&lt;/body&gt;  

&lt;body onload="&amp;#97lert('Hi')"&gt;&lt;/body&gt; 的情况下,解析器能够创建body 标签,一旦在body 标签内,它也能够创建onload 属性。一旦进入属性,所有内容都会被解析为字符串。

【讨论】:

  • 那么,问题是编码的HTML编码字符没有被解析?但是,如果我对警报方法进行编码,它能够将其检测为 JavaScript。这就是我觉得有点困惑。
猜你喜欢
  • 2018-09-04
  • 1970-01-01
  • 2013-05-31
  • 2014-05-17
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多