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
了
非对称密码算法=>对称密码算法(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 |
|
私钥泄露
因为非对称加密算法
利用私钥生成jwt
,利用公钥解密jwt
,所以我们只要有私钥然后自己就可以重新生成
1 |
|
如果运行报错Error: secretOrPrivateKey has a minimum key size of 2048 bits for RS256
可以强行注释node_modules\jsonwebtoken\sign.js
中对于密钥长度的判断
其他
听说还有通过KID实现任意文件读取,注入等操作,CVE-2018-0114,CVE-2022-39227,下次抽空研究下
工具
参考文章:
JSON Web Token (JWT) 攻击技巧
JWT原理及常见攻击方式
JWT总结
CVE-2022-39227漏洞分析