DOM XSS(跨站脚本攻击)是一种基于文档对象模型(DOM)的客户端漏洞,攻击者通过控制用户输入(source)并将其传递到动态代码执行的接收器(sink),从而在浏览器中执行恶意JavaScript代码。
一、DOM XSS的核心机制- DOM定义:DOM是浏览器中表示HTML/XML/SVG等文档的对象模型,JavaScript可通过DOM API动态操作文档内容。若攻击者能控制输入并影响DOM操作逻辑,则可能触发漏洞。
- 漏洞本质:攻击者通过构造恶意输入,使JavaScript代码从可控来源(如URL参数、Cookie、本地存储等)传递到危险接收器(如innerHTML、eval()等),最终执行任意脚本。
二、常见攻击场景与Payload示例1. HTML Sink攻击- 正文插入:通过闭合HTML标签注入脚本。"><script>alert('XSS');</script>
- 属性注入:直接利用JavaScript函数或伪协议。<a href="javascript:alert(1)">
2. JavaScript Sink攻击- 动态执行函数:如eval()、setTimeout()等。eval('var data = "some string"'); // 攻击者可替换为恶意代码
- JSON解析绕过:利用特殊字符(如U+2028、U+2029)或</script>闭合标签注入。{"data":"</script><script>alert(1)</script>"}
3. 第三方库漏洞- AngularJS(1.6+版本):通过ng-app属性触发表达式注入。{{$on.constructor('alert(1)')()}}
- jQuery(早期版本):利用选择器创建元素时的逻辑缺陷。<iframe src="
https://target.com/#"
onload="this.src+='<img src=x onerror=alert(1)>'"></iframe>当hashchange事件触发时,jQuery会解析window.location.hash并创建恶意元素。
三、关键Source与Sink分类常见Source(攻击者可控输入来源)- URL参数:window.location.search
- 引用头:document.referrer
- 本地存储:localStorage、sessionStorage
- 历史记录:history.pushState、history.replaceState
- 文档属性:document.cookie、document.URL
常见Sink(危险接收器)- DOM操作:document.write()element.innerHTML = "<img src=x onerror=alert(1)>"
- jQuery方法:$('#target').html('<script>alert(1)</script>');$.parseHTML("<div onclick=alert(1)>");
- 动态执行:eval(userInput);setTimeout("alert(" + userInput + ")", 100);
四、检测与防御工具Burp Suite DOM Invader自动化检测DOM XSS漏洞,支持分析动态数据流。
白名单过滤库
js-xss
:基于白名单的HTML过滤库。CSP(内容安全策略):通过HTTP头限制脚本执行来源。
Payload集合
PayloadsAllTheThings
:提供各类XSS攻击Payload,包括DOM XSS专项测试用例。
五、防御策略输入验证与转义
对所有用户输入进行严格验证,拒绝包含<script>、javascript:等危险字符的输入。
使用DOM API时,优先采用textContent替代innerHTML。
CSP策略配置HTTP头Content-Security-Policy,限制脚本执行来源(如仅允许同源或特定CDN)。
避免使用危险Sink
禁用eval()、setTimeout(string)等动态执行函数。
使用jQuery.text()替代jQuery.html()操作DOM。
框架安全实践
升级AngularJS、jQuery等库至最新版本,修复已知漏洞。
遵循框架安全文档(如
AngularJS安全指南
)。
六、实验与学习资源PortSwigger DOM XSS实验
:通过动手实验理解漏洞原理。美团前端安全文章
:深入分析JSON解析中的XSS绕过技巧。
通过理解DOM XSS的攻击链(Source→Sink)、掌握常见Payload构造方法,并实施严格的输入验证与CSP策略,可有效降低此类漏洞风险。