安全
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:可访问性