JWT认证漏洞攻防指南:8类漏洞利用与防御策略详解
字数 2514 2025-09-01 11:25:54

JWT认证漏洞攻防指南:8类漏洞利用与防御策略详解

1. JWT基础概念回顾

JSON Web Token (JWT)是一种开放标准(RFC 7519),用于在网络应用环境间安全地传递声明。JWT由三部分组成:

  1. Header:包含令牌类型和签名算法
  2. Payload:包含声明(claims),即用户数据
  3. Signature:用于验证消息在传递过程中没有被篡改

格式:header.payload.signature

2. JWT认证漏洞类型及利用方法

2.1 Lab1: 未验证签名的JWT认证绕过

漏洞描述
服务器接收JWT令牌后未验证签名,攻击者可以修改payload中的用户身份信息(如sub字段)来提升权限。

利用步骤

  1. 使用普通用户登录获取JWT令牌
  2. 解码JWT,修改sub字段为"administrator"
  3. 使用修改后的JWT访问/admin路径
  4. 在响应中找到管理接口(如/admin/delete?username=carlos)
  5. 调用管理接口完成攻击

防御措施

  • 服务器必须验证JWT签名
  • 使用强签名算法(如RS256)
  • 验证所有声明(claims),特别是sub、iss、aud等

2.2 Lab2: 有缺陷的签名验证绕过

漏洞描述
服务器支持"none"算法,允许无签名令牌,或者签名验证逻辑存在缺陷。

利用步骤

  1. 获取普通用户JWT令牌
  2. 修改header中的alg为"none"
  3. 删除签名部分(保留最后的点)
  4. 修改sub为"administrator"
  5. 使用修改后的令牌访问/admin路径

防御措施

  • 禁用"none"算法
  • 严格验证签名算法
  • 拒绝任何缺少签名的JWT
  • 使用固定算法列表,不依赖客户端提供的算法

2.3 Lab3: 弱签名密钥破解

漏洞描述
使用弱密钥或常见密钥签名JWT,攻击者可以暴力破解密钥。

利用步骤

  1. 尝试常见密钥(如"secret1")
  2. 使用hashcat等工具暴力破解
  3. 将破解的密钥Base64编码
  4. 使用JWT编辑器生成新密钥
  5. 修改sub为"administrator"并使用破解的密钥签名
  6. 使用新令牌访问管理接口

防御措施

  • 使用强随机密钥(至少256位)
  • 定期轮换密钥
  • 避免使用常见或默认密钥
  • 考虑使用非对称加密(如RS256)

2.4 Lab4: JWK头注入攻击

漏洞描述
服务器信任JWT头中的JWK(JSON Web Key)参数,允许攻击者注入自己的公钥。

利用步骤

  1. 生成RSA密钥对
  2. 在JWT头中添加jwk参数,指向攻击者控制的公钥
  3. 修改sub为"administrator"
  4. 使用私钥签名JWT
  5. 使用修改后的令牌访问管理接口

防御措施

  • 禁用jwk头参数
  • 使用固定密钥集
  • 验证JWK来源
  • 限制允许的密钥类型和大小

2.5 Lab5: JKU头注入攻击

漏洞描述
类似JWK注入,但通过jku(JSON Key Set URL)参数引用外部密钥集。

利用步骤

  1. 生成RSA密钥对
  2. 在攻击者控制的服务器上托管包含公钥的JWK Set
  3. 在JWT头中添加jku参数指向恶意JWK Set
  4. 修改sub为"administrator"
  5. 使用私钥签名JWT
  6. 使用修改后的令牌访问管理接口

防御措施

  • 禁用jku头参数
  • 如果必须使用,严格验证URL域名
  • 使用固定允许的jku URL白名单
  • 实施HTTPS和证书验证

2.6 Lab6: KID头路径遍历攻击

漏洞描述
kid(key ID)参数存在路径遍历漏洞,可指向系统敏感文件(如/dev/null)。

利用步骤

  1. 创建对称密钥,k值为Base64编码的空字节(AA==)
  2. 修改JWT头中的kid为路径遍历序列(如../../../../../../dev/null)
  3. 修改sub为"administrator"
  4. 使用空字节密钥签名JWT
  5. 使用修改后的令牌访问管理接口

防御措施

  • 验证kid参数,防止路径遍历
  • 限制kid为预定义值
  • 对kid进行严格输入验证
  • 使用密钥指纹而非任意kid

2.7 Lab7: 算法混淆攻击(已知公钥)

漏洞描述
当服务器使用RS256但允许HS256时,攻击者可以使用公钥作为HMAC密钥。

利用步骤

  1. 从/jwks.json获取服务器公钥
  2. 将公钥转换为PEM格式并Base64编码
  3. 创建对称密钥,k值为编码后的公钥
  4. 修改JWT头中的alg为HS256
  5. 修改sub为"administrator"
  6. 使用创建的对称密钥签名JWT
  7. 使用修改后的令牌访问管理接口

防御措施

  • 使用固定算法,不依赖客户端提供的alg
  • 拒绝算法变更(如从RS256改为HS256)
  • 为不同算法使用不同密钥
  • 验证密钥类型与算法匹配

2.8 Lab8: 算法混淆攻击(未知公钥)

漏洞描述
即使公钥未暴露,通过收集多个JWT也可以计算模数(n)并推导公钥。

利用步骤

  1. 收集同一用户的两个不同JWT
  2. 使用sig2n工具计算可能的n值
  3. 生成可能的公钥和篡改的JWT
  4. 测试每个公钥直到找到正确的
  5. 使用找到的公钥作为HMAC密钥
  6. 修改alg为HS256,sub为"administrator"
  7. 签名并访问管理接口

防御措施

  • 使用非对称加密时确保私钥安全
  • 定期轮换密钥
  • 监控异常JWT使用模式
  • 实施上述算法混淆防御措施

3. 综合防御策略

  1. 签名验证:始终验证JWT签名,拒绝无效签名
  2. 算法管理
    • 使用固定算法(推荐RS256)
    • 拒绝alg参数变更
    • 禁用"none"算法
  3. 密钥管理
    • 使用强随机密钥
    • 定期轮换密钥
    • 保护私钥安全
  4. 声明验证
    • 验证iss(签发者)、aud(受众)、exp(过期时间)等标准声明
    • 检查sub等身份声明
  5. 头参数限制
    • 禁用或严格验证jwk、jku、kid等参数
    • 防止头注入攻击
  6. 安全配置
    • 使用HTTPS传输JWT
    • 设置合理的过期时间
    • 实现令牌撤销机制
  7. 监控与日志
    • 记录异常JWT使用
    • 监控暴力破解尝试
    • 实施速率限制

通过全面实施这些防御措施,可以显著降低JWT实现中的安全风险,保护应用免受认证绕过攻击。

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实现中的安全风险,保护应用免受认证绕过攻击。