⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

6.4.1 XSS:输入验证与输出编码

一句话破题

XSS 攻击就是让你的网站帮攻击者执行 JavaScript 代码。防御的关键是:进来的要验证,出去的要编码

核心价值

理解 XSS 能让你:

  • 避免用户数据被盗
  • 保护用户账户安全
  • 通过安全审计

快速上手

React 默认防护

React 会自动转义 JSX 中的内容,这是第一道防线:

tsx
function Comment({ content }) {
  // ✅ 安全:React 自动转义
  return <div>{content}</div>
}

需要警惕的场景

tsx
// ❌ 危险:绕过 React 防护
<div dangerouslySetInnerHTML={{ __html: userContent }} />

// ❌ 危险:动态创建脚本
const script = document.createElement('script')
script.src = userInput
document.body.appendChild(script)

// ❌ 危险:eval 执行
eval(userInput)

使用 DOMPurify 清理 HTML

当确实需要渲染用户 HTML 时:

typescript
import DOMPurify from 'isomorphic-dompurify'

function SafeHtml({ html }) {
  const clean = DOMPurify.sanitize(html, {
    ALLOWED_TAGS: ['p', 'b', 'i', 'em', 'strong', 'a'],
    ALLOWED_ATTR: ['href'],
  })
  
  return <div dangerouslySetInnerHTML={{ __html: clean }} />
}

配置 CSP 响应头

Content Security Policy 限制可执行的脚本来源:

typescript
// next.config.js
module.exports = {
  async headers() {
    return [{
      source: '/:path*',
      headers: [{
        key: 'Content-Security-Policy',
        value: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"
      }]
    }]
  }
}

避坑指南

新手最容易犯的错

  1. 认为"我只是展示用户输入,不会有问题"——展示本身就是执行的入口
  2. 使用 innerHTMLdangerouslySetInnerHTML 却不清理内容
  3. 在 URL 参数中插入未验证的数据