DOM Clobbering重见天日
字数 815 2025-08-22 12:23:36

DOM Clobbering技术详解

1. 什么是DOM Clobbering

DOM Clobbering是一种利用HTML元素及其属性来覆盖或"破坏"(clobber)JavaScript全局变量或对象属性的技术。这种攻击方式在XSS和CSRF等经典客户端漏洞被修复后变得越来越重要。

2. 基本原理

DOM Clobbering的核心原理是:浏览器会自动将具有idname属性的HTML元素作为全局变量或DOM对象的属性暴露出来。

基本示例

<form id="x"><output id="y">I've been clobbered</output>
<script>
alert(x.y.value);  // 输出"I've been clobbered"
</script>

3. 元素关系确定

通过以下代码可以确定哪些HTML元素可以组合在一起形成DOM Clobbering:

var log=[];
var html = ["a","abbr","acronym",...,"xmp"]; // 所有HTML元素
var div=document.createElement('div');
for(var i=0;i<html.length;i++) {
    for(var j=0;j<html.length;j++) {
        div.innerHTML='<'+html[i]+' id=element1>'+'<'+html[j]+' id=element2>';
        document.body.appendChild(div);
        if(window.element1 && element1.element2){
            log.push(html[i]+','+html[j]);
        }
        document.body.removeChild(div);
    }
}
console.log(log.join('\n'));

测试结果显示以下元素组合有效:

form->button
form->fieldset
form->image
form->img
form->input
form->object
form->output
form->select
form->textarea

4. 使用DOM集合

可以利用idname属性创建DOM集合(类似数组的对象):

<a id="x"><a id="x" name="y" href="Clobbered">
<script>
alert(x.y)  // 输出"Clobbered"
</script>

5. 三层破坏技术

通过表单可以实现三层破坏:

<form id="x" name="y"><input id="z"></form>
<form id="x"></form>
<script>
alert(x.y.z)  // 输出input元素
</script>

6. 表单控件集合

Chrome会将表单控件集合转换为类似数组的对象([object RadioNodeList]),可以使用数组方法:

<form id="x">
<input id="y" name="z">
<input id="y">
</form>
<script>
x.y.forEach(element=>alert(element))  // 遍历所有input元素
</script>

7. 属性控制

只有HTML规范定义的属性才会成为DOM属性。可以通过以下代码查找可控属性:

var html = [...]; // HTML元素数组
var props=[];
for(i=0;i<html.length;i++){
    obj = document.createElement(html[i]);
    for(prop in obj) {
        if(typeof obj[prop] === 'string') {
            try {
                DOM.innerHTML = '<'+html[i]+' id=x '+prop+'=1>';
                if(document.getElementById('x')[prop] == 1) {
                    props.push(html[i]+':'+prop);
                }
            }catch(e){}
        }
    }
}
console.log([...new Set(props)].join('\n'));

8. 锚元素的特殊属性

锚元素的usernamepassword属性可以通过FTP URL控制:

<a id="x" href="ftp:Clobbered-username:Clobbered-Password@a">
<script>
alert(x.username)  // 输出"Clobbered-username"
alert(x.password)  // 输出"Clobbered-password"
</script>

9. 绕过URL编码

使用非标准协议可以避免URL编码:

<a id="x" href="abc:<>">
<script>
alert(x)  // 输出"abc:<>"
</script>

Firefox中可以使用base标签:

<base href="a:abc"><a id="x" href="Firefox<>">
<script>
alert(x)  // 输出"Firefox<>"
</script>

Chrome中也可以通过base标签实现:

<base href="a://Clobbered<>"><a id="x" name="x"><a id="x" name="xyz" href="123">
<script>
alert(x.xyz)  // 输出"a://Clobbered<>"
</script>

10. 多层破坏技术

使用iframesrcdoc可以实现多层破坏:

<iframe name="a" srcdoc="
<iframe srcdoc='<a id=c name=d href=cid:Clobbered>test</a><a id=c>' name=b>"></iframe>
<script>setTimeout(()=>alert(a.b.c.d),500)</script>

或者使用样式表加载延迟:

<iframe name="a" srcdoc="
<iframe srcdoc='<a id=c name=d href=cid:Clobbered>test</a><a id=c>' name=b>"></iframe>
<style>@import '//portswigger.net';</style>
<script>
alert(a.b.c.d)  // 输出"cid:Clobbered"
</script>

防御措施

  1. 使用CSP限制内联脚本
  2. 避免直接使用全局变量访问DOM元素
  3. 使用document.getElementById()等安全方法替代直接属性访问
  4. 对用户输入进行严格的过滤和转义

DOM Clobbering是一种强大的客户端攻击技术,理解其原理和实现方式对于Web安全至关重要。

DOM Clobbering技术详解 1. 什么是DOM Clobbering DOM Clobbering是一种利用HTML元素及其属性来覆盖或"破坏"(clobber)JavaScript全局变量或对象属性的技术。这种攻击方式在XSS和CSRF等经典客户端漏洞被修复后变得越来越重要。 2. 基本原理 DOM Clobbering的核心原理是:浏览器会自动将具有 id 或 name 属性的HTML元素作为全局变量或DOM对象的属性暴露出来。 基本示例 3. 元素关系确定 通过以下代码可以确定哪些HTML元素可以组合在一起形成DOM Clobbering: 测试结果显示以下元素组合有效: 4. 使用DOM集合 可以利用 id 和 name 属性创建DOM集合(类似数组的对象): 5. 三层破坏技术 通过表单可以实现三层破坏: 6. 表单控件集合 Chrome会将表单控件集合转换为类似数组的对象( [object RadioNodeList] ),可以使用数组方法: 7. 属性控制 只有HTML规范定义的属性才会成为DOM属性。可以通过以下代码查找可控属性: 8. 锚元素的特殊属性 锚元素的 username 和 password 属性可以通过FTP URL控制: 9. 绕过URL编码 使用非标准协议可以避免URL编码: Firefox中可以使用 base 标签: Chrome中也可以通过 base 标签实现: 10. 多层破坏技术 使用 iframe 和 srcdoc 可以实现多层破坏: 或者使用样式表加载延迟: 防御措施 使用 CSP 限制内联脚本 避免直接使用全局变量访问DOM元素 使用 document.getElementById() 等安全方法替代直接属性访问 对用户输入进行严格的过滤和转义 DOM Clobbering是一种强大的客户端攻击技术,理解其原理和实现方式对于Web安全至关重要。