Web安全之JWT令牌安全与攻击防护详解
字数 1301 2025-11-10 15:23:17

Web安全之JWT令牌安全与攻击防护详解

一、JWT基本概念与结构
JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息作为JSON对象。它由三部分组成,通过点号分隔:

  • Header(头部):包含令牌类型和签名算法(如HS256、RS256)
  • Payload(载荷):包含声明(用户信息、过期时间等)
  • Signature(签名):对前两部分的签名,用于验证完整性

示例结构:header.payload.signature

二、JWT的生成与验证流程

  1. 生成过程:

    • 对Header进行Base64Url编码
    • 对Payload进行Base64Url编码
    • 使用指定算法对前两部分签名:Signature = algorithm(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
    • 组合三部分形成完整JWT
  2. 验证过程:

    • 拆分JWT获取三部分
    • 重新计算签名(使用服务端密钥)
    • 对比计算签名与JWT中的签名是否一致
    • 验证过期时间等声明

三、常见JWT安全漏洞与攻击手法

  1. 算法混淆攻击:

    • 原理:将算法改为"none",绕过签名验证
    • 条件:服务端支持none算法
    • 示例:修改header为{"alg":"none","typ":"JWT"}
  2. 密钥破解攻击:

    • 原理:弱密钥可通过暴力破解
    • 工具:hashcat、jwt-cracker等
    • 防护:使用强密钥(长度≥256位)
  3. 签名验证绕过:

    • 原理:服务端未严格验证签名
    • 方式:删除签名部分、修改payload后重新组合
  4. Kid参数注入:

    • 原理:kid(Key ID)参数用于文件包含或SQL注入
    • 示例:kid="../../../../etc/passwd"

四、JWT安全防护最佳实践

  1. 算法强制验证:

    • 代码示例:
    // 错误做法:直接使用客户端提供的算法
    jwt.verify(token, secret);
    
    // 正确做法:明确指定算法
    jwt.verify(token, secret, { algorithms: ['HS256'] });
    
  2. 密钥安全管理:

    • 使用足够长度的随机密钥
    • 定期轮换密钥
    • 不同环境使用不同密钥
  3. Payload安全配置:

    • 设置合理的过期时间(exp)
    • 验证颁发者(iss)和受众(aud)
    • 使用随机jti(JWT ID)防止重放攻击
  4. 敏感信息保护:

    • 不在Payload中存储密码等敏感信息
    • 考虑使用JWE(JSON Web Encryption)进行加密

五、实际攻击案例演示

  1. 算法none攻击复现:

    • 原始JWT:header.payload.signature
    • 修改header:{"alg":"none","typ":"JWT"}
    • 重新编码:base64(header) + "." + base64(payload) + "."
    • 发送到服务端测试
  2. Kid注入攻击防御:

    • 安全代码示例:
    const key = getKeyFromTrustedSource(kid); // 从可信源获取密钥
    if (!isValidKid(kid)) { // 验证kid格式
        throw new Error('Invalid key ID');
    }
    

六、JWT安全开发检查清单

  1. □ 强制指定允许的算法白名单
  2. □ 验证签名完整性
  3. □ 检查所有声明(exp、nbf、iss等)
  4. □ 验证kid参数安全性
  5. □ 使用HTTPS传输
  6. □ 设置合理的令牌过期时间
  7. □ 实现安全的令牌刷新机制
  8. □ 记录JWT验证日志用于审计

通过以上分层讲解,可以从JWT基础原理到实际安全防护建立完整知识体系,帮助在开发和面试中全面掌握JWT安全问题。

Web安全之JWT令牌安全与攻击防护详解 一、JWT基本概念与结构 JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息作为JSON对象。它由三部分组成,通过点号分隔: Header(头部):包含令牌类型和签名算法(如HS256、RS256) Payload(载荷):包含声明(用户信息、过期时间等) Signature(签名):对前两部分的签名,用于验证完整性 示例结构:header.payload.signature 二、JWT的生成与验证流程 生成过程: 对Header进行Base64Url编码 对Payload进行Base64Url编码 使用指定算法对前两部分签名:Signature = algorithm(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 组合三部分形成完整JWT 验证过程: 拆分JWT获取三部分 重新计算签名(使用服务端密钥) 对比计算签名与JWT中的签名是否一致 验证过期时间等声明 三、常见JWT安全漏洞与攻击手法 算法混淆攻击: 原理:将算法改为"none",绕过签名验证 条件:服务端支持none算法 示例:修改header为{"alg":"none","typ":"JWT"} 密钥破解攻击: 原理:弱密钥可通过暴力破解 工具:hashcat、jwt-cracker等 防护:使用强密钥(长度≥256位) 签名验证绕过: 原理:服务端未严格验证签名 方式:删除签名部分、修改payload后重新组合 Kid参数注入: 原理:kid(Key ID)参数用于文件包含或SQL注入 示例:kid="../../../../etc/passwd" 四、JWT安全防护最佳实践 算法强制验证: 代码示例: 密钥安全管理: 使用足够长度的随机密钥 定期轮换密钥 不同环境使用不同密钥 Payload安全配置: 设置合理的过期时间(exp) 验证颁发者(iss)和受众(aud) 使用随机jti(JWT ID)防止重放攻击 敏感信息保护: 不在Payload中存储密码等敏感信息 考虑使用JWE(JSON Web Encryption)进行加密 五、实际攻击案例演示 算法none攻击复现: 原始JWT:header.payload.signature 修改header:{"alg":"none","typ":"JWT"} 重新编码:base64(header) + "." + base64(payload) + "." 发送到服务端测试 Kid注入攻击防御: 安全代码示例: 六、JWT安全开发检查清单 □ 强制指定允许的算法白名单 □ 验证签名完整性 □ 检查所有声明(exp、nbf、iss等) □ 验证kid参数安全性 □ 使用HTTPS传输 □ 设置合理的令牌过期时间 □ 实现安全的令牌刷新机制 □ 记录JWT验证日志用于审计 通过以上分层讲解,可以从JWT基础原理到实际安全防护建立完整知识体系,帮助在开发和面试中全面掌握JWT安全问题。