XSS 跨站脚本防护指南:防御前端安全威胁

跨站脚本攻击(Cross-Site Scripting,简称 XSS)是 Web 应用中最常见的安全漏洞之一。OWASP Top 10 自 2010 年以来持续将 XSS 列为最突出的安全风险之一。XSS 攻击允许攻击者向目标网站注入恶意脚本,在用户浏览器中执行,从而窃取敏感信息、劫持用户会话、篡改页面内容或传播恶意软件。

一、XSS 攻击的类型

1. 反射型 XSS(Reflected XSS)

反射型 XSS 是最基础的 XSS 形式。恶意脚本嵌入在 URL 参数中,当用户点击特制的链接时,服务器将未经过滤的脚本「反射」回浏览器执行。

攻击流程:

  • 攻击者构造包含恶意脚本的 URL:https://example.com/search?q=<script>alert('XSS')</script>
  • 用户点击链接后,服务器将参数值直接渲染到页面中
  • 浏览器执行脚本,攻击达成

反射型 XSS 通常需要诱骗用户点击链接,常结合社交工程手段如钓鱼邮件、短链接等。

2. 存储型 XSS(Stored XSS)

存储型 XSS 的危害更大。恶意脚本被持久化存储在服务器端(如数据库、评论系统、用户资料等),每当其他用户访问受影响的页面时,脚本自动执行。

典型场景:

  • 攻击者在评论区提交包含 <script> 标签的评论
  • 服务器未过滤直接存入数据库
  • 其他用户浏览该文章时,恶意脚本在浏览器中自动执行

存储型 XSS 覆盖面广、持续性长,是最危险的 XSS 类型。

3. DOM 型 XSS(DOM-based XSS)

DOM 型 XSS 的独特之处在于攻击完全发生在客户端。服务器响应中不包含恶意代码,攻击通过 JavaScript 操作 DOM 时的不安全处理触发。

常见触发点:

  • document.write()、innerHTML 等直接操作 HTML 的 API
  • eval()、setTimeout() 等动态执行字符串的 API
  • 从 location.hash、location.search、document.referrer 等来源获取数据后未安全处理

二、XSS 攻击的潜在危害

XSS 攻击可以造成以下严重后果:

危害类型 说明 严重程度
Cookie 窃取 通过 document.cookie 窃取会话凭证 严重
会话劫持 使用窃取的 Cookie 冒充用户登录 严重
页面篡改 修改页面内容进行钓鱼或欺诈 中
键盘记录 捕获用户的键盘输入(密码、信用卡号) 严重
恶意跳转 将用户重定向到钓鱼网站 中
CSRF 配合 在用户不知情的情况下发起跨站请求 严重
挖矿脚本 在用户浏览器中植入挖矿脚本消耗设备资源 低

三、XSS 防御策略

1. 输出编码(Output Encoding)

输出编码是最核心的 XSS 防御手段。根据上下文选择正确的编码方式:

上下文 编码方式 示例
HTML 标签内容 HTML 实体编码 &lt;、&gt;
HTML 属性 HTML 属性编码 &quot; 避免逃逸
JavaScript 字符串 Unicode 转义 \x3C、\u003C
URL 参数 URL 编码 %3Cscript%3E
CSS 值 CSS 转义 \3C

2. 输入验证(Input Validation)

  • 白名单验证:只允许预期的字符和格式,比黑名单更安全
  • 长度限制:限制输入长度减少攻击面
  • 格式验证:对邮箱、URL、电话号码等使用正则表达式验证格式
  • 数据清理:移除或拒绝包含 HTML 标签的输入(依赖于具体业务场景)

3. Content Security Policy(CSP)

CSP 是浏览器层面的安全机制,通过 HTTP 响应头声明允许加载的资源来源。即使攻击者成功注入了代码,CSP 也能阻止其执行。

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'

CSP 配置要点:

  • 严格限制 script-src,避免使用 'unsafe-inline'
  • 使用 nonce 或 hash 机制允许特定内联脚本
  • 拒绝 eval() 及相关函数(移除 'unsafe-eval')
  • 通过 report-uri 收集违规报告

4. 框架内置防护

现代前端框架和模板引擎内置了 XSS 防护机制,应充分利用:

框架 默认防护机制 注意事项
React JSX 默认对输出进行编码 使用 dangerouslySetInnerHTML 需谨慎
Vue 模板插值 {{ }} 自动编码 v-html 指令会输出原始 HTML
Angular 内置 DOM Sanitizer 使用 DomSanitizer.bypassSecurityTrustHtml 需谨慎
Django 模板 自动 HTML 转义 safe 过滤器会关闭转义
Thymeleaf 默认文本模式转义 utext 属性会输出未经转义的 HTML

5. 安全 HTTP 头配置

# 禁用 XSS 审计(浏览器已逐步弃用)
X-XSS-Protection: 0

# 防止 MIME 类型嗅探
X-Content-Type-Options: nosniff

# 控制 iframe 嵌入
X-Frame-Options: DENY

# Content Security Policy
Content-Security-Policy: script-src 'self'; object-src 'none'

6. HttpOnly Cookie

设置 Cookie 的 HttpOnly 标志可以阻止 JavaScript 通过 document.cookie 访问 Cookie,有效防御基于 XSS 的会话凭证窃取。

Set-Cookie: sessionid=xxx; HttpOnly; Secure; SameSite=Strict

四、XSS 检测工具

工具 类型 说明
OWASP ZAP 开源 自动扫描 XSS 和其他 Web 漏洞
Burp Suite 商业 专业级 Web 安全测试工具
DomGoat 开源 专门检测 DOM 型 XSS
XSStrike 开源 高级 XSS 检测工具
Acunetix 商业 自动化 Web 漏洞扫描
ESLint 安全插件 开源 代码静态分析中检测不安全 API

五、XSS 防御检查清单

开发阶段应逐项检查:

  • 所有用户输入是否经过了上下文相关的输出编码?
  • 是否配置了严格的 CSP 策略?
  • 是否设置了 HttpOnly、Secure、SameSite Cookie 标志?
  • 前端框架是否使用了安全的 API(避免 innerHTML、document.write)?
  • 第三方库是否已经更新到最新版本(无已知 XSS 漏洞)?
  • eval()、setTimeout(string)、new Function() 是否已禁用?
  • 用户上传的文件名和内容是否经过验证?
  • JSONP 接口是否有限制回调函数名的验证?
  • 是否在 CI/CD 流程中集成了自动化 XSS 扫描?

六、16IDC 观察

XSS 是一个已被广泛认知但仍在持续发生的安全问题。防御 XSS 不存在银弹,需要在开发、测试、部署全链路中实施纵深防御。

在实践中,最容易出现 XSS 漏洞的场景往往是「方便快捷的代码捷径」——比如为了快速开发而使用 innerHTML 替代 textContent,或者为了方便而绕过框架的安全机制。

对于中小团队,建议优先做好两件事:配置严格的 CSP 策略(可以阻止大部分 XSS 攻击),以及在代码审查中重点检查用户数据的输出处理。这两项措施能以最小的投入覆盖最大的风险面。