挖洞经验 | 篡改JWT实现账户劫持
字数 1553 2025-08-15 21:30:55

JWT安全漏洞分析与防御指南

1. JWT基础概念

1.1 什么是JWT

JSON Web Token (JWT) 是基于RFC 7519标准定义的,以JSON形式在网络应用间安全传递信息的一种紧凑而独立的方法,尤其适用于分布式站点的单点登录(SSO)场景。

1.2 JWT结构组成

JWT由三部分组成,各部分之间用点(.)分隔:

  • Header(头部): 包含令牌类型和签名算法
  • Payload(负载): 包含声明(claims),即要传输的数据
  • Signature(签名): 用于验证消息在传输过程中未被篡改

格式示例:xxxxx.yyyyy.zzzzz

2. 漏洞发现与分析

2.1 漏洞背景

目标系统在邀请功能中使用JWT进行用户验证,但存在以下安全问题:

  • JWT在客户端生成而非服务端
  • 缺乏对JWT签名的有效验证
  • 允许用户修改关键字段而不进行重新验证

2.2 攻击步骤详解

2.2.1 初始信息收集

  1. 攻击者使用自己的邮箱(attacker@attacker.com)发起邀请
  2. 系统发送包含JWT的确认链接到攻击者邮箱
  3. 使用工具(如jwt.io)解码JWT获取结构

2.2.2 管理员账户劫持

  1. 攻击者尝试邀请管理员邮箱(admin@company.com)
  2. 获取包含管理员相关信息的JWT响应
  3. 修改JWT中的关键字段:
    • 将邀请人邮箱改为admin@company.com
    • 修改用户ID为管理员ID
    • 调整时间戳(created date)
  4. 重新编码生成新的JWT
  5. 使用篡改后的JWT进行身份验证和密码重置

2.2.3 普通用户密码重置

  1. 注册测试用户(Victim),获取其用户ID(如jyAzV7KhT)
  2. 使用攻击者邮箱发起密码重置请求
  3. 获取包含JWT的重置链接
  4. 修改JWT中的用户ID为Victim的ID
  5. 使用篡改后的JWT重置Victim账户密码

3. 漏洞根本原因

  1. 客户端生成JWT:目标系统错误地在客户端生成JWT,而非在服务端
  2. 缺乏签名验证:系统未正确验证JWT签名,允许篡改后的token通过验证
  3. 过度信任客户端数据:系统完全信任JWT中的声明而不进行二次验证
  4. 关键业务逻辑缺陷:密码重置流程设计不当,依赖可被篡改的客户端数据

4. 漏洞利用条件

  1. 需要知道目标用户的ID
  2. 系统使用客户端生成的JWT
  3. 系统不对JWT签名进行严格验证
  4. 系统允许通过JWT直接进行敏感操作(如密码重置)

5. 防御措施

5.1 安全开发实践

  1. 服务端生成JWT:所有JWT应在服务端生成,避免客户端篡改
  2. 严格签名验证:实现强制的签名验证机制
  3. 使用强密钥:采用足够强度的密钥进行签名
  4. 限制JWT有效期:设置合理的过期时间(exp claim)

5.2 业务逻辑加固

  1. 二次验证机制:对于敏感操作(如密码重置),应结合其他验证方式
  2. 关键字段绑定:将JWT中的用户ID与当前会话绑定验证
  3. 操作日志记录:记录所有关键操作的JWT使用情况
  4. 黑名单机制:对已使用的JWT进行标记,防止重复使用

5.3 技术实现建议

  1. 使用标准的JWT库而非自行实现
  2. 避免在URL中传输JWT(可能被记录),使用Authorization头
  3. 对不同的业务场景使用不同的签名密钥
  4. 定期轮换签名密钥

6. 测试与验证方法

  1. 篡改测试:尝试修改JWT各字段验证系统是否检测
  2. 签名测试:使用无效签名验证系统是否拒绝
  3. 过期测试:使用过期的JWT验证系统是否拒绝
  4. 重放测试:重复使用已使用的JWT验证系统是否检测

7. 相关资源

  1. JWT官方介绍
  2. JWT安全最佳实践
  3. JWT漏洞案例研究

通过以上措施,可有效防御JWT篡改导致的账户劫持等安全问题。开发人员应始终遵循"不信任客户端数据"的原则,对关键操作实施多层验证机制。

JWT安全漏洞分析与防御指南 1. JWT基础概念 1.1 什么是JWT JSON Web Token (JWT) 是基于RFC 7519标准定义的,以JSON形式在网络应用间安全传递信息的一种紧凑而独立的方法,尤其适用于分布式站点的单点登录(SSO)场景。 1.2 JWT结构组成 JWT由三部分组成,各部分之间用点(.)分隔: Header(头部) : 包含令牌类型和签名算法 Payload(负载) : 包含声明(claims),即要传输的数据 Signature(签名) : 用于验证消息在传输过程中未被篡改 格式示例: xxxxx.yyyyy.zzzzz 2. 漏洞发现与分析 2.1 漏洞背景 目标系统在邀请功能中使用JWT进行用户验证,但存在以下安全问题: JWT在客户端生成而非服务端 缺乏对JWT签名的有效验证 允许用户修改关键字段而不进行重新验证 2.2 攻击步骤详解 2.2.1 初始信息收集 攻击者使用自己的邮箱(attacker@attacker.com)发起邀请 系统发送包含JWT的确认链接到攻击者邮箱 使用工具(如jwt.io)解码JWT获取结构 2.2.2 管理员账户劫持 攻击者尝试邀请管理员邮箱(admin@company.com) 获取包含管理员相关信息的JWT响应 修改JWT中的关键字段: 将邀请人邮箱改为admin@company.com 修改用户ID为管理员ID 调整时间戳(created date) 重新编码生成新的JWT 使用篡改后的JWT进行身份验证和密码重置 2.2.3 普通用户密码重置 注册测试用户(Victim),获取其用户ID(如jyAzV7KhT) 使用攻击者邮箱发起密码重置请求 获取包含JWT的重置链接 修改JWT中的用户ID为Victim的ID 使用篡改后的JWT重置Victim账户密码 3. 漏洞根本原因 客户端生成JWT :目标系统错误地在客户端生成JWT,而非在服务端 缺乏签名验证 :系统未正确验证JWT签名,允许篡改后的token通过验证 过度信任客户端数据 :系统完全信任JWT中的声明而不进行二次验证 关键业务逻辑缺陷 :密码重置流程设计不当,依赖可被篡改的客户端数据 4. 漏洞利用条件 需要知道目标用户的ID 系统使用客户端生成的JWT 系统不对JWT签名进行严格验证 系统允许通过JWT直接进行敏感操作(如密码重置) 5. 防御措施 5.1 安全开发实践 服务端生成JWT :所有JWT应在服务端生成,避免客户端篡改 严格签名验证 :实现强制的签名验证机制 使用强密钥 :采用足够强度的密钥进行签名 限制JWT有效期 :设置合理的过期时间(exp claim) 5.2 业务逻辑加固 二次验证机制 :对于敏感操作(如密码重置),应结合其他验证方式 关键字段绑定 :将JWT中的用户ID与当前会话绑定验证 操作日志记录 :记录所有关键操作的JWT使用情况 黑名单机制 :对已使用的JWT进行标记,防止重复使用 5.3 技术实现建议 使用标准的JWT库而非自行实现 避免在URL中传输JWT(可能被记录),使用Authorization头 对不同的业务场景使用不同的签名密钥 定期轮换签名密钥 6. 测试与验证方法 篡改测试 :尝试修改JWT各字段验证系统是否检测 签名测试 :使用无效签名验证系统是否拒绝 过期测试 :使用过期的JWT验证系统是否拒绝 重放测试 :重复使用已使用的JWT验证系统是否检测 7. 相关资源 JWT官方介绍 JWT安全最佳实践 JWT漏洞案例研究 通过以上措施,可有效防御JWT篡改导致的账户劫持等安全问题。开发人员应始终遵循"不信任客户端数据"的原则,对关键操作实施多层验证机制。