JWT安全风险全解析:攻击手段与防护要点
字数 2003 2025-08-29 08:30:12
JWT安全风险全解析:攻击手段与防护要点
1. JWT基础概念
1.1 什么是JWT
JSON Web令牌(JWT)是一种标准化格式,用于在系统之间发送经过加密签名的JSON数据。它最常用于身份验证、会话处理和访问控制机制中发送关于用户的信息("声明")。
1.2 JWT特点
- 服务器所需的所有数据都存储在客户端的JWT本身中
- 特别适合高度分布式网站,用户需要与多个后端服务器无缝交互
- 由3部分组成:头部(Header)、负载(Payload)和签名(Signature)
1.3 JWT格式示例
eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0lOtps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIylFdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA
2. JWT组成部分详解
2.1 头部(Header)
- Base64Url编码的JSON对象
- 包含关于令牌本身的元数据
- 常用字段:
alg:签名算法(如HS256、RS256等)typ:令牌类型(通常为"JWT")kid:密钥ID(可选)
2.2 负载(Payload)
- Base64Url编码的JSON对象
- 包含关于用户的实际"声明"
- 声明类型:
- 注册声明(预定义):iss(签发者)、exp(过期时间)、sub(主题)、aud(受众)等
- 公共声明:可自定义但应在IANA JSON Web Token Registry中注册
- 私有声明:自定义声明,用于在同意使用它们的各方之间共享信息
2.3 签名(Signature)
- 用于验证令牌未被篡改
- 生成方式:对头部和负载进行哈希(有时还会加密),使用秘密签名密钥
- 验证原理:
- 更改头部或负载的单个字节将导致签名不匹配
- 不知道服务器秘密签名密钥时,无法为给定头部和负载生成正确签名
3. JWT相关规范
3.1 JWT与JWS/JWE关系
- JWT规范本身非常有限,仅定义了一种信息表示格式
- 通过JWS(JSON Web签名)和JWE(JSON Web加密)规范扩展实现
- 常见情况:
- "JWT"通常指JWS令牌(内容仅编码)
- JWE令牌内容被加密
4. JWT攻击概述
4.1 什么是JWT攻击
用户向服务器发送修改后的JWT,以实现恶意目标,通常是冒充其他已通过身份验证的用户来绕过身份验证和访问控制。
4.2 攻击影响
- 严重性高
- 攻击者可提升权限或完全控制其他用户账户
4.3 漏洞原因
- 应用程序对JWT处理不当
- JWT规范灵活性导致实现细节由开发人员决定
- 常见问题:
- 签名未正确验证
- 秘密密钥泄露或可被猜出/暴力破解
5. JWT攻击手段详解
5.1 签名验证缺陷利用
服务器通常不存储JWT信息,每个令牌是完全独立实体。如果服务器未正确验证签名,攻击者可随意更改令牌内容。
示例攻击场景:
- 修改
username值冒充其他用户 - 修改
isAdmin值提升权限
5.2 接受任意签名
- 开发人员混淆
verify()和decode()方法 - 仅使用
decode()方法意味着不验证签名
靶场示例:
JWT Authentication Bypass via Unverified Signature
5.3 其他常见攻击手段
(文章未完全展开,此处补充常见攻击类型)
-
算法混淆攻击(Algorithm Confusion)
- 将算法从RS256改为HS256
- 利用公钥作为HMAC密钥
-
无效签名攻击
- 删除签名部分(保留末尾的点)
- 设置
alg为"none"
-
密钥泄露攻击
- 暴力破解弱密钥
- 通过信息泄露获取密钥
-
密钥ID注入(KID Injection)
- 操纵
kid头参数指向攻击者控制的密钥
- 操纵
-
JWK头参数注入
- 在头部注入
jwk参数提供恶意公钥
- 在头部注入
-
过期时间绕过
- 修改
exp声明延长令牌有效期
- 修改
6. JWT安全防护要点
6.1 基本防护措施
-
始终验证签名
- 使用正确的验证方法(如
verify()而非decode()) - 确保验证所有部分的完整性
- 使用正确的验证方法(如
-
使用强算法
- 优先使用RS256而非HS256
- 避免使用"none"算法
-
密钥管理
- 使用足够强度的密钥
- 定期轮换密钥
- 保护密钥不被泄露
-
声明验证
- 验证
iss(签发者)、aud(受众)等声明 - 严格检查
exp和nbf时间声明
- 验证
6.2 进阶防护措施
-
密钥ID安全
- 验证
kid头参数指向可信密钥 - 防止目录遍历攻击
- 验证
-
限制头部参数
- 拒绝包含
jwk或x5c等危险头参数的令牌
- 拒绝包含
-
令牌撤销机制
- 实现令牌黑名单
- 短期令牌有效期
-
安全传输
- 始终使用HTTPS
- 设置适当的CORS策略
-
安全库使用
- 使用经过安全审计的JWT库
- 保持库版本更新
7. 总结
JWT作为一种流行的身份验证机制,其安全性高度依赖于正确的实现和使用。开发人员必须:
- 充分理解JWT工作原理和安全风险
- 严格验证所有令牌和声明
- 实施健全的密钥管理策略
- 使用安全配置的、经过验证的库
- 定期进行安全审计和测试
通过遵循这些最佳实践,可以显著降低JWT实现中的安全风险,保护应用免受身份验证和授权绕过攻击。