JWT常见安全问题学习总结
Json web token(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519)。它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为JSON对象,特别适用于分布式站点的单点登录(SSO)场景。
结构
jwt由三部分组成:header、payload、signature,用点.分隔
header
header 用来声明 token 的类型和签名用的算法等
示例
1 | |
经过 Base64Url 编码后构成了 JWT 的第一部分
payload
payload 就是存放有效信息的地方
示例
1 | |
它的声明有三类:已注册声明(Registered claims),公共声明(public claims), 私人声明(private claims)
其中已注册声明有7个默认字段,都由官方所定义(参考rfc7519),但并不都是必需的
1 | |
公共声明 :这些可以由使用JWT的人随意定义。但是为了避免冲突,它们应该在IANA JSON Web令牌注册表中定义,或者定义为包含抗冲突命名空间的 URI。
私人声明 :这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公共声明
经过 Base64Url 编码后构成了 JWT 的第二部分
signature
签名用于验证消息在此过程中没有被更改
这个部分需要 Base64Url 编码后的 header 和 Base64Url 编码后的 payload 使用 . 连接,组成字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,然后就构成了 jwt 的第三部分
如果要使用 HMAC SHA256 算法,将按以下方式创建签名
1 | |
secret是保存在服务端的,jwt的签发生成也是在服务端的,secret就是用来进行jwt的签发和jwt的验证,所以一旦客户端得知这个secret, 那就意味着客户端可以自我签发jwt了
安全问题
敏感信息泄露
因为 payload 和 header 只经过 Base64Url 编码,如果开发者把一些敏感信息存放到里面,我们可以轻松获得
未校验签名
某些服务端并未校验JWT签名,所以,可以尝试修改 signature 后(或者直接删除 signature )看其是否还有效
签名算法置空(CVE-2015-2951)
我们知道,签名算法可以确保JWT在传输过程中不会被恶意用户所篡改
但头部中的 alg 字段却可以改为 none ,服务端接收到后会将其认定为无加密算法, 于是对 signature 的检验也就失效了,那么我们就可以随意修改 payload 部分伪造 token
因为 jwt.io 将 alg 为 none 视为恶意行为,所以无法通过在线工具生成JWT,可以用 python 的 jwt 库来实现
1 | |
运行结果eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY3NDAzMTA5MSwiZXhwIjoxNjc0MDM4MjkxLCJuYmYiOjE2NzQwMzEwOTEsInN1YiI6ImFkbWluIiwianRpIjoiZTQxZmY0NDFiMDRiZjMzN2FiM2NhNzE1ZjY0YTc2ZTEifQ.
签名密钥爆破
JWT使用算法对 header 和 payload 进行加密,如果我们可以爆破出加密密钥,那么也就可以随意修改 token 了

两个jwt碰撞获取密钥:jwt_forgery.py
非对称密码算法=>对称密码算法(CVE-2016-10555)
JWT的签名加密算法有两种,对称加密算法和非对称加密算法
对称加密算法比如HS256使用密钥为所有消息进行签名和验证
非对称加密算法比如RS256使用私钥对消息进行签名并使用公钥进行身份验证
如果我们获取到了公钥,可以将头部中的算法修改从 RS256 更改为 HS256 ,这样后端代码就会使用 RSA 公钥+ HS256 算法进行签名验证
js代码实现
1 | |
python代码实现
不过用python跑的时候因为jwt版本过高会报错 The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret
解决方法: pip install pyjwt==0.4.3
1 | |
例如2025 ccb Deprecated

decode的时候支持使用非对称RS256和对称HS256,但是签名的时候用的是非对称加密RS256
如果能拿到公钥,那么就可以任意身份伪造(可以用上面的两个jwt碰撞获取密钥)
1 | |
私钥泄露
因为 非对称加密算法 利用私钥生成 jwt ,利用公钥解密 jwt ,所以我们只要有私钥然后自己就可以重新生成
1 | |
如果运行报错 Error: secretOrPrivateKey has a minimum key size of 2048 bits for RS256
可以强行注释 node_modules\jsonwebtoken\sign.js 中对于密钥长度的判断

JSON Web Token (JWT) 攻击技巧
JWT原理及常见攻击方式
JWT总结
CVE-2022-39227漏洞分析