web安全战技101之JWT
字数 2012 2025-08-13 21:33:17

JWT安全攻防实战指南

1. JWT基础原理

1.1 JWT与传统Session机制对比

传统Session ID机制

  • 服务器存储会话信息
  • 使用会话cookie授权
  • 服务器需要维护会话状态

JWT机制

  • 服务器不存储会话信息
  • 使用JSON Web Token授权
  • 令牌自包含用户信息
  • 服务器只需验证签名

1.2 JWT结构解析

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

头部.负载.签名

头部(Header)

  • Base64编码
  • 包含算法和令牌类型
  • 示例:{"alg":"HS256","typ":"JWT"}

负载(Payload)

  • 包含用户信息(claims)
  • 常见字段:
    • sub:用户标识(类似session ID)
    • iat:发布时间(issued at)
    • exp:过期时间(expiration time)
    • name:用户名
    • 自定义字段(如admin表示管理员权限)

签名(Signature)

  • 使用头部指定的算法生成
  • 公式:HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
  • 确保令牌完整性

2. JWT安全测试方法论

2.1 测试思路

基于JWT原理的测试方法:

  1. 并发测试

    • 高并发注册账户,观察生成的JWT数量、有效期和一致性
  2. 注销测试

    • 注销后重新登录,检查是否下发相同JWT
    • 验证之前下发的JWT是否失效
  3. 令牌篡改测试

    • 发送伪造JWT
    • 发送空令牌
    • 发送多个令牌
  4. 验证绕过测试

    • 绕过验证机制
    • 弱比较验证测试
  5. 响应分析

    • 检查响应包中的客户端hook重定向
    • 分析是否使用OAUTH 2.0

2.2 关键测试点

  1. 密钥安全性

    • 密钥应仅存储在服务器端
    • 检查密钥是否泄露在客户端
  2. 过期时间

    • 检查exp字段
    • 测试过期令牌是否仍可使用
  3. 签名验证

    • 验证服务器是否正确验证签名
    • 测试篡改后令牌是否被拒绝

3. JWT常见漏洞与攻击手法

3.1 算法None攻击

原理

  • 将头部中的算法改为none
  • 服务器可能不验证签名
  • 允许攻击者篡改负载

攻击步骤

  1. 解码JWT头部
  2. 修改算法为none
  3. Base64编码回头部
  4. 篡改负载(如将admin改为true)
  5. 删除签名部分或保留空签名
  6. 发送修改后的令牌

变体尝试

  • none
  • None
  • nOnE
  • NONE

3.2 算法混淆攻击(CVE-2015-9235)

原理

  • 服务器配置使用RSA验证
  • 攻击者将算法改为HS256
  • 使用RSA公钥作为HS256的密钥签名

攻击步骤

  1. 获取服务器RSA公钥
  2. 修改头部算法为HS256
  3. 篡改负载
  4. 使用公钥作为密钥生成新签名
  5. 发送伪造的JWT

3.3 其他攻击手法

  1. 密钥暴力破解

    • 对弱密钥进行暴力破解
    • 使用工具如jwt-cracker
  2. 令牌泄露

    • 通过XSS、日志泄露等获取有效令牌
    • 重放攻击
  3. 令牌过期绕过

    • 删除exp字段
    • 修改过期时间为未来时间

4. 实战环境搭建

4.1 测试工具

  1. Burp Suite扩展

    • JSON Web Tokens:用于调试JWT
    • JSON Web Tokens Attacker:用于攻击测试
  2. 在线工具

    • https://jwt.io/:JWT调试
    • https://www.onelogin.com/:授权测试网站

4.2 靶机环境

WebGoat靶机

  • GitHub仓库:https://github.com/WebGoat/WebGoat
  • 部署方式:
    java -jar webgoat-server-8.2.1.jar [--server.port=8080] [--server.address=localhost]
    java -jar webwolf-8.2.1.jar [--server.port=9090] [--server.address=localhost]
    

Docker部署

sudo docker pull webgoat/goatandwolf
sudo docker run -p 8080:8080 -p 9090:9090 -e TZ=Europe/Amsterdam webgoat/goatandwolf

5. 实战案例:WebGoat JWT挑战

5.1 挑战目标

  • 修改JWT获取管理员权限
  • 重置投票计数

5.2 攻击步骤

  1. 捕获正常请求

    • 使用Burp Suite拦截投票请求
    • 分析JWT结构
  2. 解码JWT

    • 使用jwt.io或Burp扩展解码
    • 发现admin: false字段
  3. None算法攻击

    • 修改头部算法为none
    • admin改为true
    • 删除签名部分
  4. 发送篡改后的请求

    • 观察响应,确认权限提升
    • 多次发送以验证投票计数变化
  5. 功能点测试

    • 寻找重置功能点
    • 重复攻击过程

6. 防御建议

  1. 严格算法验证

    • 拒绝none算法
    • 只允许预期的算法类型
  2. 密钥管理

    • 使用强密钥
    • 定期轮换密钥
    • 确保密钥不泄露
  3. 令牌验证

    • 严格验证签名
    • 检查过期时间
    • 实现令牌吊销机制
  4. 其他措施

    • 限制令牌使用范围
    • 监控异常令牌使用
    • 使用HTTPS传输令牌

7. 总结

JWT作为现代Web应用常用的授权机制,虽然提供了便利性,但也引入了新的安全风险。安全测试人员应深入理解JWT工作原理,掌握常见攻击手法,并在SDL过程中系统性地测试JWT实现的安全性。通过本指南提供的原理分析、测试方法和实战案例,安全工程师可以有效地识别和防范JWT相关漏洞。

JWT安全攻防实战指南 1. JWT基础原理 1.1 JWT与传统Session机制对比 传统Session ID机制 : 服务器存储会话信息 使用会话cookie授权 服务器需要维护会话状态 JWT机制 : 服务器不存储会话信息 使用JSON Web Token授权 令牌自包含用户信息 服务器只需验证签名 1.2 JWT结构解析 JWT由三部分组成,用点(.)分隔: 头部(Header) : Base64编码 包含算法和令牌类型 示例: {"alg":"HS256","typ":"JWT"} 负载(Payload) : 包含用户信息(claims) 常见字段: sub :用户标识(类似session ID) iat :发布时间(issued at) exp :过期时间(expiration time) name :用户名 自定义字段(如 admin 表示管理员权限) 签名(Signature) : 使用头部指定的算法生成 公式: HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 确保令牌完整性 2. JWT安全测试方法论 2.1 测试思路 基于JWT原理的测试方法: 并发测试 : 高并发注册账户,观察生成的JWT数量、有效期和一致性 注销测试 : 注销后重新登录,检查是否下发相同JWT 验证之前下发的JWT是否失效 令牌篡改测试 : 发送伪造JWT 发送空令牌 发送多个令牌 验证绕过测试 : 绕过验证机制 弱比较验证测试 响应分析 : 检查响应包中的客户端hook重定向 分析是否使用OAUTH 2.0 2.2 关键测试点 密钥安全性 : 密钥应仅存储在服务器端 检查密钥是否泄露在客户端 过期时间 : 检查 exp 字段 测试过期令牌是否仍可使用 签名验证 : 验证服务器是否正确验证签名 测试篡改后令牌是否被拒绝 3. JWT常见漏洞与攻击手法 3.1 算法None攻击 原理 : 将头部中的算法改为 none 服务器可能不验证签名 允许攻击者篡改负载 攻击步骤 : 解码JWT头部 修改算法为 none Base64编码回头部 篡改负载(如将 admin 改为 true ) 删除签名部分或保留空签名 发送修改后的令牌 变体尝试 : none None nOnE NONE 3.2 算法混淆攻击(CVE-2015-9235) 原理 : 服务器配置使用RSA验证 攻击者将算法改为HS256 使用RSA公钥作为HS256的密钥签名 攻击步骤 : 获取服务器RSA公钥 修改头部算法为HS256 篡改负载 使用公钥作为密钥生成新签名 发送伪造的JWT 3.3 其他攻击手法 密钥暴力破解 : 对弱密钥进行暴力破解 使用工具如 jwt-cracker 令牌泄露 : 通过XSS、日志泄露等获取有效令牌 重放攻击 令牌过期绕过 : 删除 exp 字段 修改过期时间为未来时间 4. 实战环境搭建 4.1 测试工具 Burp Suite扩展 : JSON Web Tokens:用于调试JWT JSON Web Tokens Attacker:用于攻击测试 在线工具 : https://jwt.io/:JWT调试 https://www.onelogin.com/:授权测试网站 4.2 靶机环境 WebGoat靶机 : GitHub仓库:https://github.com/WebGoat/WebGoat 部署方式: Docker部署 : 5. 实战案例:WebGoat JWT挑战 5.1 挑战目标 修改JWT获取管理员权限 重置投票计数 5.2 攻击步骤 捕获正常请求 : 使用Burp Suite拦截投票请求 分析JWT结构 解码JWT : 使用jwt.io或Burp扩展解码 发现 admin: false 字段 None算法攻击 : 修改头部算法为 none 将 admin 改为 true 删除签名部分 发送篡改后的请求 : 观察响应,确认权限提升 多次发送以验证投票计数变化 功能点测试 : 寻找重置功能点 重复攻击过程 6. 防御建议 严格算法验证 : 拒绝 none 算法 只允许预期的算法类型 密钥管理 : 使用强密钥 定期轮换密钥 确保密钥不泄露 令牌验证 : 严格验证签名 检查过期时间 实现令牌吊销机制 其他措施 : 限制令牌使用范围 监控异常令牌使用 使用HTTPS传输令牌 7. 总结 JWT作为现代Web应用常用的授权机制,虽然提供了便利性,但也引入了新的安全风险。安全测试人员应深入理解JWT工作原理,掌握常见攻击手法,并在SDL过程中系统性地测试JWT实现的安全性。通过本指南提供的原理分析、测试方法和实战案例,安全工程师可以有效地识别和防范JWT相关漏洞。