基于DOM的XSS漏洞与防护(进阶篇)
字数 1650 2025-11-22 04:35:32
基于DOM的XSS漏洞与防护(进阶篇)
1. 漏洞描述
基于DOM的XSS(DOM-based Cross-Site Scripting)是一种客户端漏洞,攻击者通过操纵页面的DOM(文档对象模型)环境来注入恶意脚本。与反射型或存储型XSS不同,DOM型XSS的恶意代码完全在客户端执行,无需经过服务器响应(即请求和响应中可能看不到恶意载荷)。其核心原理是:
- 页面JavaScript从攻击者可控的源(如URL的
document.location.hash、document.referrer等)获取数据。 - 数据未经过安全处理就被传递给危险的DOM操作(如
innerHTML、eval()、document.write())。
2. 漏洞产生场景示例
假设一个页面通过JavaScript解析URL中的参数并动态更新内容:
<!-- 页面URL:http://example.com/page.html#<img src=x onerror=alert(1)> -->
<script>
const data = document.location.hash.substring(1); // 获取#后的内容
document.getElementById("content").innerHTML = data; // 直接插入DOM
</script>
<div id="content"></div>
攻击者构造恶意URL,用户访问时触发XSS。
3. 漏洞挖掘与攻击向量
步骤1:识别数据源
- 检查所有客户端可控的源:
document.URL/document.location(href、pathname、search、hash)document.referrerwindow.namelocalStorage/sessionStorage- 通过
postMessage接收的数据
步骤2:跟踪数据流向
- 使用代码审计或动态工具(如浏览器开发者工具的断点调试)跟踪数据是否传递至以下危险函数:
innerHTML/outerHTMLdocument.write()eval()/setTimeout()/setInterval()(动态执行字符串)location/open()(跳转或新窗口注入)
步骤3:构造绕过Payload
- 若存在基础过滤(如删除
<script>标签),尝试以下绕过技术:- 使用其他标签触发事件(如
<img onerror=alert(1)>)。 - 利用JavaScript协议(如
<a href="javascript:alert(1)">)。 - 通过DOM解析差异(如
<svg><script>alert(1)</script>)。
- 使用其他标签触发事件(如
4. 防护方案
原则:对可控数据实施严格的上下文感知转义
方案1:避免使用危险API
- 用
textContent替代innerHTML,避免直接插入HTML。 - 用
JSON.parse()替代eval()解析数据。
方案2:上下文相关转义
- 若必须插入HTML,使用以下规则:
- HTML上下文:转义
< > & ' "(如<变为<)。 - 属性上下文:转义
" '及空格(如"变为")。 - JavaScript上下文:使用
\uXXXX格式转义特殊字符。
- HTML上下文:转义
- 推荐使用成熟库(如DOMPurify)进行过滤。
方案3:白名单验证
- 对输入数据格式严格校验(如仅允许字母数字)。
- 使用CSP(内容安全策略)限制脚本执行源:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
方案4:安全编码实践
- 避免将可控数据与字符串拼接后传递给
eval()或new Function()。 - 使用
postMessage时验证消息来源(event.origin)。
5. 进阶绕过与防护对抗
- CSP绕过:若允许
unsafe-eval或存在允许域,可尝试JSONP回调注入。 - DOM Clobbering攻击:通过插入特定HTML元素(如
<a id="x">)覆盖DOM属性,影响JS逻辑。防护需避免全局变量与DOM元素ID冲突。
6. 测试与验证
- 使用自动化工具(如DOMInvader、Burp Suite DOM Invader插件)辅助检测。
- 手动测试时重点关注动态内容更新环节,观察数据流是否经过危险操作。
通过以上步骤,可系统化理解DOM型XSS的成因、利用方式及防护要点,提升代码安全性与漏洞挖掘能力。