XSS 漏洞全解析:反射型、存储型与 DOM 型跨站脚本攻击的挖掘与防御

跨站脚本攻击(Cross-Site Scripting,简称 XSS)是 Web 安全领域中最常见、最持久的漏洞类型之一。尽管现代框架和浏览器不断引入新的防护机制,XSS 依然在 OWASP Top 10 中占据重要位置。本文将从漏洞原理出发,系统梳理反射型、存储型和 DOM 型三种 XSS 的挖掘方法与防御策略。

一、XSS 漏洞的本质

XSS 的核心在于:攻击者能够将恶意脚本注入到网页中,并使其在其他用户的浏览器中执行。这打破了同源策略的边界——原本只应运行受信任代码的页面,却执行了攻击者可控的 JavaScript,从而导致 Cookie 窃取、会话劫持、钓鱼攻击、键盘记录等一系列严重后果。

从数据流的角度看,一个 XSS 漏洞的产生需要满足三个条件:

  1. 入口:攻击者能够向 Web 应用输入可控数据;
  2. 出口:这些数据未经充分处理就被输出到 HTML 页面中;
  3. 执行:浏览器将输出内容解析为可执行的脚本代码。

二、反射型 XSS

2.1 原理

反射型 XSS(Reflected XSS)是最常见的形式。攻击者构造一个带有恶意脚本的 URL,诱导受害者点击。服务器将 URL 中的参数直接“反射”回响应页面中,浏览器随即执行其中的脚本。

例如,一个搜索页面将关键词直接输出到结果页:

https://example.com/search?q=<script>alert(document.cookie)</script>

如果服务端未做转义,页面就会执行这段脚本。

2.2 挖掘方法

  • 参数遍历:对 URL 中所有 GET/POST 参数逐一注入测试 payload,观察是否被原样输出。
  • 编码绕过:尝试 URL 编码、HTML 实体编码、双写等方式绕过简单过滤。
  • 上下文判断:确认输出点位于 HTML 标签之间、属性值内还是 JavaScript 代码块中,不同上下文需要不同的闭合方式。
  • 工具辅助:Burp Suite 的 Intruder 模块、XSStrike 等可自动化检测。

2.3 特点

反射型 XSS 不具有持久性,每次攻击都需要诱导用户点击特定链接。因此,它常被用于钓鱼邮件或社交工程攻击中。

三、存储型 XSS

3.1 原理

存储型 XSS(Stored XSS)的危害性最大。攻击者将恶意脚本提交到服务器并持久化存储(如数据库、文件系统),当其他用户访问包含该数据的页面时,脚本自动执行。

典型场景包括:评论区、用户昵称、论坛帖子、日志展示页面等。

3.2 挖掘方法

  • 寻找持久化输入点:任何会被保存并展示给其他用户的功能都值得关注。
  • 测试输出位置:提交 payload 后,检查它在哪些页面、以何种方式被渲染。
  • 关注富文本编辑器:富文本场景下过滤规则往往更复杂,容易出现遗漏。
  • 二次注入:某些数据可能先存储、后在管理后台或邮件模板中被渲染,形成“存储 + 反射”的组合。

3.3 特点

存储型 XSS 无需诱导点击,只要用户访问受影响的页面就会中招,且影响范围可能覆盖大量用户,甚至形成蠕虫式传播(如经典的 Samy 蠕虫)。

四、DOM 型 XSS

4.1 原理

DOM 型 XSS(DOM-based XSS)的独特之处在于:恶意数据不经过服务器端处理,完全在客户端 JavaScript 中完成“源(source)→ 汇(sink)”的流动。

常见的 source 包括:location.hreflocation.hashdocument.referrerwindow.name 等。
危险的 sink 包括:innerHTMLouterHTMLdocument.writeevalsetTimeout 等。

例如:

var name = location.hash.substring(1);
document.getElementById("greeting").innerHTML = "Hello, " + name;

访问 https://example.com/#<img src=x onerror=alert(1)> 即可触发。

4.2 挖掘方法

  • 审计 JavaScript 代码:重点查找 source 到 sink 的赋值链路。
  • 使用浏览器开发者工具:在 Sources 面板中设置断点,追踪数据流。
  • 动态测试:在 hash、referrer 等位置注入 payload,观察 DOM 变化。
  • 工具:DOM Invader(Burp Suite 内置)、Chrome DevTools 的 DOM 断点功能。

4.3 特点

DOM 型 XSS 难以被服务端 WAF 检测,因为恶意 payload 从不发送到服务器。服务端日志中也看不到攻击痕迹,给检测和取证带来挑战。

五、三种类型的对比

类型 数据是否经过服务器 持久性 典型触发方式 检测难度
反射型 诱导点击恶意链接
存储型 访问被污染页面 低(但危害大)
DOM 型 诱导点击特殊 URL

六、防御策略

6.1 输出编码

根据输出上下文(HTML、属性、JavaScript、CSS、URL)采用对应的编码方式。例如,HTML 上下文使用 HTML 实体编码,JavaScript 上下文使用 \x 转义。这是最根本的防御手段。

6.2 输入验证与白名单

对用户输入进行格式校验,尽可能采用白名单策略。例如,邮箱字段只允许合法邮箱格式,年龄字段只允许数字。

6.3 内容安全策略(CSP)

通过 HTTP 响应头 Content-Security-Policy 限制脚本来源,禁止内联脚本执行。例如:

Content-Security-Policy: default-src 'self'; script-src 'self'

CSP 能有效缓解 XSS 的影响,但配置不当也可能被绕过。

6.4 使用安全 API

避免使用 innerHTMLdocument.write 等危险 API,改用 textContentsetAttribute 等安全方法。现代前端框架(React、Vue)默认对插值进行转义,但 dangerouslySetInnerHTMLv-html 等仍需谨慎。

6.5 HttpOnly Cookie

为敏感 Cookie 设置 HttpOnly 属性,使 JavaScript 无法读取,从而降低会话劫持风险。

6.6 其他措施

  • 设置 X-XSS-Protection(虽已逐渐被 CSP 取代);
  • 对富文本使用成熟的白名单过滤库(如 DOMPurify);
  • 定期进行安全测试与代码审计。

七、结语

XSS 漏洞看似简单,实则变化多端。反射型、存储型和 DOM 型各有其独特的挖掘思路与防御重点。理解数据从输入到输出的完整链路,是发现和修复 XSS 的关键。在实际工作中,应将输出编码作为默认习惯,辅以 CSP、安全 API 和持续的安全测试,构建多层次的防御体系。唯有如此,才能在这个“永远在线”的时代,守住用户浏览器的最后一道防线。

未经允许不得转载:任鹏个人博客 » XSS 漏洞全解析:反射型、存储型与 DOM 型跨站脚本攻击的挖掘与防御

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏