跳转到主要内容

安全

React 默认对 XSS 有一定防护,但安全是系统性的:输入、输出、依赖与部署链路都要考虑。

一个好用的心智模型是:把所有外部字符串都当作不可信输入,并设计边界让“安全路径”成为默认选项。

React 中的 XSS 基础

React 默认会转义文本,降低一部分 XSS 风险,但你仍可能通过 HTML 注入、URL 注入、第三方脚本引入漏洞。

  • `JSX` 文本节点默认会转义。
  • 危险点主要在“注入原始 HTML”和“不安全的 URL 处理”。

原始 HTML:默认不可信

一旦你渲染用户可控的 HTML,就进入 `XSS` 高危区。只有在你能严格 `sanitize` 且限制功能时才考虑。

如果你在做富文本,优先使用结构化文档模型并自行渲染。“HTML 字符串”往往是事故高发区。

  • 优先用结构化表示(受限 `Markdown`、富文本模型)替代“HTML 字符串”。
  • 必须渲染时,用可信白名单 `sanitize`,并移除危险属性(`on*` 事件、`style`、`srcdoc`)。

安全 URL 处理(链接、图片)

`XSS` 不只来自 HTML。URL 型攻击(`javascript:`、`data:`)也可能在 `href`/`src` 中触发执行。

一个简单基线是:只允许 `http:`/`https:`(可选 `mailto:`),其余一律拒绝。

TypeScript
export function safeUrl(input: string) {
  try {
    const url = new URL(input, 'https://example.com');
    const protocol = url.protocol.toLowerCase();
    if (protocol === 'http:' || protocol === 'https:' || protocol === 'mailto:') {
      return url.href;
    }
    return null;
  } catch {
    return null;
  }
}

第三方脚本

第三方脚本属于供应链风险。每引入一个脚本,你的攻击面都会扩大。

  • 把第三方脚本视为“以你站点权限执行的代码”。要限制数量并审查。
  • 尽量按需加载,能隔离就隔离(子域、sandbox iframe)。

部署与 CSP

`CSP` 可以通过限制脚本来源来缓解一类 `XSS` 风险。建议先用 `report-only` 模式观察,再逐步收紧。

把 CSP 当作迁移:先观察、再修违规、最后 enforced。目标不是第一天就完美,而是形成持续收紧的闭环。

Bash
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'

依赖卫生

现实世界里很多安全事故来自依赖问题。把升级与扫描常态化,避免在危机时才“被迫大修”。

  • 固定并审查重大升级;保持升级节奏,避免跨度过大。
  • 在 `CI` 自动做漏洞扫描;高危问题作为发布阻断。

上线检查清单

  • 不渲染未 `sanitize` 的原始 HTML;必须有白名单。
  • 用户提供的 URL 在进入 `href`/`src` 前已校验/允许列表过滤。
  • `CSP` 已启用(先 `report-only`,再 enforced)。
  • 依赖已扫描,升级进入常规流程。

延伸阅读

安全 - Guides - React 文档 - React 文档