← 中文资源

简体中文版本

跨站脚本攻击(XSS)

XSS 把攻击者控制的脚本注入他人浏览的页面。输出编码、安全 DOM API 与 CSP 限制执行,单靠输入校验不够。

阅读英文原文

三种投递路径

反射型 XSS 把请求值回显到响应;存储型 XSS 持久化载荷并提供给后续用户;DOM 型 XSS 由客户端代码把不可信数据写入 innerHTML 等危险位置,服务端未参与。

在输出点防御

// ❌ HTML 注入
container.innerHTML = `<p>${userInput}</p>`;

// ✅ textContent 把值当作文本
const p = document.createElement('p');
p.textContent = userInput;
container.append(p);

如果确实需要 HTML,使用维护良好的白名单库清洗,并按具体上下文编码。给 href 或 src 赋值前校验协议,只允许 https:、mailto: 和明确批准的其他协议。

纵深防御

  • 针对 HTML、属性、JavaScript、CSS 与 URL 上下文分别编码。
  • 使用框架的安全 API,避免原始 HTML 写入点。
  • 配置带 nonce 或哈希的严格 CSP。
  • 会话 Cookie 设置 HttpOnly,使脚本无法读取。
  • 使用经过审查的库清洗 Markdown 与富文本。

何时最重要

任何展示其他用户或外部系统内容的页面都是候选。与 CSRF 相比,XSS 攻击用户对页面本身的信任,并可以读取用户能看到的数据;CSRF 则在不读取响应的情况下触发动作。两者都需要上下文相关防御,而不是一个全局过滤器。

陷阱

只黑名单 <script> 会漏掉事件处理器、SVG 和编码后的载荷。先转义再解码会重新打开漏洞。存储未清洗的 HTML 并依赖客户端清理,会把漏洞转移给每一个消费方。