JWT 常见测试点
字数 2405 2025-11-21 12:10:37
JWT 安全测试全面指南
一、JWT 基础与工作流程
1.1 JWT 基本结构
JWT(JSON Web Token)由三部分组成,以点号分隔:
- Header:包含令牌类型和签名算法
- Payload:包含声明(用户信息、权限等)
- Signature:对前两部分的签名,用于验证完整性
1.2 JWT 工作流程
- 用户认证:客户端提交账号密码到认证服务器(HTTPS)
- 令牌生成:服务器验证通过后,使用密钥生成签名后的JWT
- 令牌返回:JWT返回给客户端存储
- API访问:客户端在请求头中携带JWT访问受保护资源
- 服务器验证:服务器解析并验证JWT签名
- 授权处理:验证成功后读取Payload中的用户信息进行授权
二、JWT 安全漏洞类型与测试方法
2.1 未验证签名绕过
漏洞原理:服务端未对JWT签名进行验证,直接信任Payload内容
测试步骤:
- 使用正常账号登录系统,捕获JWT令牌
- 解析Payload,识别用户标识字段(如account、unionid)
- 修改Payload中的用户标识为其他合法用户
- 保持原有签名或使用相同算法重新签名
- 使用伪造的JWT访问API接口
漏洞验证:成功访问目标用户数据即存在漏洞
修复方案:
- 严格验证JWT签名有效性
- 身份信息应以数据库或会话验证为准
- 实施服务端资源访问身份匹配校验
2.2 有缺陷的签名验证绕过
漏洞原理:服务端错误处理alg=none情况,跳过签名验证
测试步骤:
- 正常登录获取JWT令牌
- 将Header中的alg参数修改为"none"
- 修改Payload中的用户身份为管理员
- 移除签名部分(或保留空签名)
- 使用修改后的令牌访问权限接口
漏洞代码示例:
alg = decodeHeader(token).alg
if (alg == 'none') {
// 错误:跳过签名验证
payload = decodePayload(token)
}
修复方案:
- 拒绝接受alg=none的令牌
- 严格校验JWT签名,仅接受配置的算法
- 使用正确的密钥对,不允许客户端推测密钥
2.3 弱签名密钥绕过
漏洞原理:使用弱密钥或常见密钥进行HS256签名,易被爆破
测试方法:
- 获取正常JWT令牌(HS256算法)
- 使用工具爆破签名密钥(如jwt_tool.py)
- 使用爆破出的密钥伪造管理员令牌
- 替换原令牌访问管理功能
常用爆破密钥:secret、key、password等弱密钥
修复方案:
- 使用高强度随机密钥(≥32字节)
- 采用非对称签名算法(RS256)
- 定期更换签名密钥
2.4 JWT头部注入绕过
2.4.1 JWK头部注入
漏洞原理:服务端信任header中的jwk参数,使用攻击者公钥验证
测试步骤:
- 生成RSA密钥对
- 在JWT头部添加jwk字段,包含公钥信息
- 使用私钥对修改后的令牌签名
- 服务端使用注入的公钥验证通过
修复方案:
- 禁止解析JWT header中的jwk字段
- 固定使用服务器配置的验证密钥
2.4.2 JKU头部注入
漏洞原理:服务端从指定URL加载公钥进行验证
测试步骤:
- 在可控服务器托管包含公钥的JWK集合文件
- 修改JWT头部jku字段指向该URL
- 使用对应私钥签名伪造令牌
- 服务端从指定URL加载公钥验证
修复方案:
- 禁用jku头部或实施严格白名单
- 固定使用本地配置的公钥源
2.5 KID标头路径遍历
漏洞原理:KID参数存在路径遍历漏洞,可读取系统文件
测试方法:
- 修改KID参数为路径遍历形式(如../../../etc/passwd)
- 服务端尝试读取指定文件作为密钥
- 利用文件读取失败的回退机制绕过验证
修复方案:
- 严格校验KID参数格式
- 禁止路径遍历字符
- 密钥文件不存储在Web可访问目录
2.6 算法混淆攻击
漏洞原理:利用服务器算法验证缺陷,将非对称算法误用为对称算法
测试方法:
方法一:公钥作为对称密钥
- 获取服务器RS256公钥
- 将公钥Base64编码作为HS256的对称密钥
- 修改alg为HS256,使用公钥签名伪造令牌
方法二:令牌派生公钥(无密钥暴露)
- 收集多个服务器签名的JWT令牌
- 使用工具(如jwt_forgery.py)逆向推导公钥
- 利用推导的公钥进行算法混淆攻击
修复方案:
- 强制指定验证算法,不依赖header参数
- 验证密钥类型与算法匹配性
- 使用标准算法和足够长度的密钥
2.7 敏感信息泄露
漏洞原理:JWT Payload或Header中包含敏感信息
测试方法:
- Base64解码JWT各部分
- 检查是否包含密码、密钥等敏感数据
- 利用泄露信息进行进一步攻击
常见泄露点:
- 用户密码或密钥
- 内部系统信息
- 加密密钥或种子
修复方案:
- 实施令牌版本控制(token_version)
- 验证时检查令牌版本与数据库一致性
- 避免在JWT中存储敏感信息
三、JWT安全最佳实践
3.1 签名验证规范
- 始终验证JWT签名有效性
- 拒绝alg=none的令牌
- 使用强密码学算法(RS256优于HS256)
3.2 密钥管理
- 使用高强度随机生成密钥
- 定期更换签名密钥
- 安全存储私钥,避免泄露
3.3 头部参数处理
- 禁用不可信的头部参数(jwk、jku、x5u)
- 严格校验KID参数格式和范围
- 实施公钥源白名单机制
3.4 令牌生命周期管理
- 设置合理的令牌过期时间
- 实现令牌撤销机制
- 使用令牌版本控制防止重放
3.5 安全开发实践
- 使用经过验证的JWT库
- 实施完整的错误处理机制
- 定期进行安全审计和渗透测试
四、测试工具推荐
4.1 常用测试工具
- jwt_tool.py:JWT漏洞测试和密钥爆破
- Burp Suite JWT插件:Burp集成测试功能
- jwt.io:在线JWT解码和验证
4.2 自定义测试脚本
开发自定义测试脚本针对特定实现进行深度测试,重点关注算法验证、密钥管理和头部处理等关键环节。
通过系统化的测试方法和严格的安全实践,可以有效发现和修复JWT实现中的安全漏洞,确保身份验证机制的安全性。