JWT安全漏洞与防护(实战进阶篇)
字数 1410 2025-11-17 15:03:55
JWT安全漏洞与防护(实战进阶篇)
知识点描述
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全传输信息。其结构分为头部(Header)、载荷(Payload)和签名(Signature)三部分,通过签名验证令牌的完整性。然而,错误实现或配置可能导致严重安全漏洞,如算法混淆、密钥泄露、无效签名验证等。本主题将深入分析JWT实战中的高级漏洞场景及防护措施。
解题过程循序渐进讲解
-
JWT基础结构回顾
- 头部(Header):包含令牌类型(如"JWT")和签名算法(如HS256、RS256)。示例:
{"alg": "HS256", "typ": "JWT"} - 载荷(Payload):存放实际数据(如用户ID、权限),分标准声明(如
exp过期时间)和自定义声明。 - 签名(Signature):对头部和载荷的Base64URL编码字符串拼接后,使用密钥和指定算法生成签名,防止篡改。
- 头部(Header):包含令牌类型(如"JWT")和签名算法(如HS256、RS256)。示例:
-
关键漏洞场景与攻击手法
-
算法混淆攻击(Algorithm Confusion)
- 原理:攻击者将算法从非对称(如RS256)改为对称(如HS256),利用公钥作为密钥伪造签名。
- 攻击步骤:
- 获取服务器公钥(可能通过信息泄露或端点暴露);
- 修改JWT头部为
{"alg": "HS256", "typ": "JWT"}; - 使用公钥作为HS256的密钥,生成新签名;
- 发送篡改后的JWT绕过验证。
- 防护:代码中强制指定预期算法(如
JWT.verify(token, key, ["RS256"])),而非依赖令牌内的算法字段。
-
无效签名验证(None Algorithm)
- 原理:部分库支持
alg: "none",允许无签名令牌。攻击者删除签名部分,诱使服务器跳过验证。 - 防护:禁用
none算法,并验证签名是否存在。
- 原理:部分库支持
-
密钥泄露与弱密钥
- 场景:硬编码弱密钥(如"password")或密钥通过不安全渠道传输。
- 攻击:爆破常见密钥(使用工具如
jwt_tool)或利用泄露密钥伪造令牌。 - 防护:使用强随机密钥,定期轮换,避免硬编码。
-
载荷篡改(如Kid注入)
- 原理:
kid(密钥ID)参数可能用于从文件系统或数据库加载密钥。若未过滤,攻击者可注入路径(如"kid": "../../public/key.pem")或SQL语句。 - 防护:严格校验
kid值,限制为白名单标识符。
- 原理:
-
-
实战漏洞利用示例
- 案例:通过Kid参数进行路径遍历
- 原始JWT载荷:
{"user": "admin", "kid": "default_key"} - 修改
kid为"../../../etc/passwd",服务器可能误用该文件内容作为验证密钥,导致签名绕过。
- 原始JWT载荷:
- 防护代码示例(Node.js):
jwt.verify(token, key, { algorithms: ["RS256"] }, (err, decoded) => { if (err) throw new Error("Invalid token"); // 校验kid是否在白名单内 if (!validKids.includes(decoded.header.kid)) reject(); });
- 案例:通过Kid参数进行路径遍历
-
深度防护策略
- 最佳实践:
- 使用非对称算法(如RS256)避免密钥共享风险。
- 设置短过期时间(如15分钟),结合刷新令牌机制。
- 对敏感操作强制重新认证。
- 库选择:采用经过安全审计的库(如
jsonwebtoken),并及时更新。 - 日志监控:记录JWT验证失败事件,检测异常活动(如频繁算法变更)。
- 最佳实践:
-
测试与验证
- 工具辅助:使用
jwt_tool或Burp Suite插件自动化测试算法混淆、签名绕过等漏洞。 - 代码审计:检查是否强制验证算法、是否合理处理
kid和jku(JWK Set URL)参数。
- 工具辅助:使用
通过以上步骤,可系统化识别和修复JWT实现中的安全隐患,确保令牌机制的可靠性和安全性。