JWT认证漏洞攻防指南:8类漏洞利用与防御策略详解
字数 2514 2025-09-01 11:25:54
JWT认证漏洞攻防指南:8类漏洞利用与防御策略详解
1. JWT基础概念回顾
JSON Web Token (JWT)是一种开放标准(RFC 7519),用于在网络应用环境间安全地传递声明。JWT由三部分组成:
- Header:包含令牌类型和签名算法
- Payload:包含声明(claims),即用户数据
- Signature:用于验证消息在传递过程中没有被篡改
格式:header.payload.signature
2. JWT认证漏洞类型及利用方法
2.1 Lab1: 未验证签名的JWT认证绕过
漏洞描述:
服务器接收JWT令牌后未验证签名,攻击者可以修改payload中的用户身份信息(如sub字段)来提升权限。
利用步骤:
- 使用普通用户登录获取JWT令牌
- 解码JWT,修改sub字段为"administrator"
- 使用修改后的JWT访问/admin路径
- 在响应中找到管理接口(如/admin/delete?username=carlos)
- 调用管理接口完成攻击
防御措施:
- 服务器必须验证JWT签名
- 使用强签名算法(如RS256)
- 验证所有声明(claims),特别是sub、iss、aud等
2.2 Lab2: 有缺陷的签名验证绕过
漏洞描述:
服务器支持"none"算法,允许无签名令牌,或者签名验证逻辑存在缺陷。
利用步骤:
- 获取普通用户JWT令牌
- 修改header中的alg为"none"
- 删除签名部分(保留最后的点)
- 修改sub为"administrator"
- 使用修改后的令牌访问/admin路径
防御措施:
- 禁用"none"算法
- 严格验证签名算法
- 拒绝任何缺少签名的JWT
- 使用固定算法列表,不依赖客户端提供的算法
2.3 Lab3: 弱签名密钥破解
漏洞描述:
使用弱密钥或常见密钥签名JWT,攻击者可以暴力破解密钥。
利用步骤:
- 尝试常见密钥(如"secret1")
- 使用hashcat等工具暴力破解
- 将破解的密钥Base64编码
- 使用JWT编辑器生成新密钥
- 修改sub为"administrator"并使用破解的密钥签名
- 使用新令牌访问管理接口
防御措施:
- 使用强随机密钥(至少256位)
- 定期轮换密钥
- 避免使用常见或默认密钥
- 考虑使用非对称加密(如RS256)
2.4 Lab4: JWK头注入攻击
漏洞描述:
服务器信任JWT头中的JWK(JSON Web Key)参数,允许攻击者注入自己的公钥。
利用步骤:
- 生成RSA密钥对
- 在JWT头中添加jwk参数,指向攻击者控制的公钥
- 修改sub为"administrator"
- 使用私钥签名JWT
- 使用修改后的令牌访问管理接口
防御措施:
- 禁用jwk头参数
- 使用固定密钥集
- 验证JWK来源
- 限制允许的密钥类型和大小
2.5 Lab5: JKU头注入攻击
漏洞描述:
类似JWK注入,但通过jku(JSON Key Set URL)参数引用外部密钥集。
利用步骤:
- 生成RSA密钥对
- 在攻击者控制的服务器上托管包含公钥的JWK Set
- 在JWT头中添加jku参数指向恶意JWK Set
- 修改sub为"administrator"
- 使用私钥签名JWT
- 使用修改后的令牌访问管理接口
防御措施:
- 禁用jku头参数
- 如果必须使用,严格验证URL域名
- 使用固定允许的jku URL白名单
- 实施HTTPS和证书验证
2.6 Lab6: KID头路径遍历攻击
漏洞描述:
kid(key ID)参数存在路径遍历漏洞,可指向系统敏感文件(如/dev/null)。
利用步骤:
- 创建对称密钥,k值为Base64编码的空字节(AA==)
- 修改JWT头中的kid为路径遍历序列(如../../../../../../dev/null)
- 修改sub为"administrator"
- 使用空字节密钥签名JWT
- 使用修改后的令牌访问管理接口
防御措施:
- 验证kid参数,防止路径遍历
- 限制kid为预定义值
- 对kid进行严格输入验证
- 使用密钥指纹而非任意kid
2.7 Lab7: 算法混淆攻击(已知公钥)
漏洞描述:
当服务器使用RS256但允许HS256时,攻击者可以使用公钥作为HMAC密钥。
利用步骤:
- 从/jwks.json获取服务器公钥
- 将公钥转换为PEM格式并Base64编码
- 创建对称密钥,k值为编码后的公钥
- 修改JWT头中的alg为HS256
- 修改sub为"administrator"
- 使用创建的对称密钥签名JWT
- 使用修改后的令牌访问管理接口
防御措施:
- 使用固定算法,不依赖客户端提供的alg
- 拒绝算法变更(如从RS256改为HS256)
- 为不同算法使用不同密钥
- 验证密钥类型与算法匹配
2.8 Lab8: 算法混淆攻击(未知公钥)
漏洞描述:
即使公钥未暴露,通过收集多个JWT也可以计算模数(n)并推导公钥。
利用步骤:
- 收集同一用户的两个不同JWT
- 使用sig2n工具计算可能的n值
- 生成可能的公钥和篡改的JWT
- 测试每个公钥直到找到正确的
- 使用找到的公钥作为HMAC密钥
- 修改alg为HS256,sub为"administrator"
- 签名并访问管理接口
防御措施:
- 使用非对称加密时确保私钥安全
- 定期轮换密钥
- 监控异常JWT使用模式
- 实施上述算法混淆防御措施
3. 综合防御策略
- 签名验证:始终验证JWT签名,拒绝无效签名
- 算法管理:
- 使用固定算法(推荐RS256)
- 拒绝alg参数变更
- 禁用"none"算法
- 密钥管理:
- 使用强随机密钥
- 定期轮换密钥
- 保护私钥安全
- 声明验证:
- 验证iss(签发者)、aud(受众)、exp(过期时间)等标准声明
- 检查sub等身份声明
- 头参数限制:
- 禁用或严格验证jwk、jku、kid等参数
- 防止头注入攻击
- 安全配置:
- 使用HTTPS传输JWT
- 设置合理的过期时间
- 实现令牌撤销机制
- 监控与日志:
- 记录异常JWT使用
- 监控暴力破解尝试
- 实施速率限制
通过全面实施这些防御措施,可以显著降低JWT实现中的安全风险,保护应用免受认证绕过攻击。