JSON Web Tokens (JWT)
1. JWT 是什么?
JSON Web Token(JWT)。它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。这使得JWT成为高度分布式网站的热门选择,在这些网站中,用户需要与多个后端服务器无缝交互。
JWT 的核心特点
- 无状态(Stateless):服务器不需要存储会话信息,所有数据都包含在 Token 中。
- 可自包含(Self-contained):Payload 可以携带用户信息,如 ID、角色、权限等。
- 可签名(Signed):使用 HMAC 或 RSA 等算法进行签名,防止篡改。
- 可加密(Encrypted)(JWE):可选加密,确保数据保密性(较少使用,通常仅签名)。
JWT的结构
JWT由三部分组成,用点(.)分隔:
- Header (头部)
- Payload (有效载荷)
- Signature (签名)
格式如下:
Header.Payload.Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
(1) Header(头部)
- 包含 Token 类型 和 签名算法。
- 采用 Base64Url 编码。
{
"alg": "HS256", // 签名算法(如 HS256、RS256、ES256)
"typ": "JWT" // Token 类型
}
(2) Payload(载荷)
- 存放 用户数据 和 声明(Claims)。
- 采用 Base64Url 编码。
标准声明(Registered Claims)
字段 | 含义 |
---|---|
iss (Issuer) | Token 签发者 |
sub (Subject) | Token 面向的用户 |
aud (Audience) | Token 接收方 |
exp (Expiration Time) | Token 过期时间(Unix 时间戳) |
nbf (Not Before) | Token 生效时间 |
iat (Issued At) | Token 签发时间 |
jti (JWT ID) | Token 唯一标识 |
自定义声明(Custom Claims)
Payload是JWT的第二个部分,这是一个JSON对象,主要承载了各种声明并传递明文数据,用于存储用户的信息,如id、用户名、角色、令牌生成时间和其他自定义声明。
可以添加任意数据,如:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
(3) Signature(签名)
-
用于 验证 Token 是否被篡改。
-
签名方式取决于
alg
指定的算法:- HS256(HMAC + SHA256):对称加密,使用 同一个密钥 签名和验证。
- RS256(RSA + SHA256):非对称加密,使用 私钥签名,公钥验证。
要创建签名部分,你需要:
- 编码后的header
- 编码后的payload
- 一个密钥
- header中指定的算法
签名生成方式
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret_key
)
2. JWT 的安全问题
常见攻击方式
攻击方式 | 描述 | 防御措施 |
---|---|---|
签名未验证 | 服务器不验证签名,导致伪造 Token | 必须验证签名 |
弱密钥爆破 | 使用弱密钥(如 secret 、password ) | 使用强密钥 |
算法混淆 | 修改 alg: HS256 ,用 RSA 公钥作为 HMAC 密钥 | 强制指定算法 |
jwk/jku 注入 | 攻击者提供恶意公钥 | 禁止动态加载密钥 |
kid 路径遍历 | 修改 kid 指向攻击者控制的密钥 | 严格校验 kid |
Token 重放 | 截获 Token 后重复使用 | 设置短有效期,使用 jti |
3.复盘文章
复盘:
https://mp.weixin.qq.com/s/ITVFuQpA8OCIRj4wW-peAA
https://mp.weixin.qq.com/s/xuY1oTwFcM1pyiql0U3NPQ
https://mp.weixin.qq.com/s/AVW8DsnLiviopeJYQYKC3A
https://mp.weixin.qq.com/s/st0xma6KoRbo1NUp9rtZhw
https://mp.weixin.qq.com/s/9OL5jZK7S1MiEUb8Q_F1Pw
4.技巧
首先找到需要JWT鉴权后才能访问的页面,如个人资料页面,将请求重放测试:
1)未授权访问:删除Token后仍然可以正常响应对应页面
2)敏感信息泄露:通过JWt.io解密出Payload后查看其中是否包含敏感信息,如弱加密的密码等
3)破解密钥+越权访问:通过JWT.io解密出Payload部分内容,通过空加密算法或密钥爆破等方式实现重新签发Token并修改Payload部分内容,重放请求包,观察响应包是否能够越权查看其他用户资料
4)检查Token时效性:解密查看payload中是否有exp字段键值对(Token过期时间),等待过期时间后再次使用该Token发送请求,若正常响应则存在Token不过期
5)通过页面回显进行探测:如修改Payload中键值对后页面报错信息是否存在注入,payload中kid字段的目录遍历问题与sql注入问题
5.识别检测利用项目:
BURP插件:Hae&JSON Web Tokens&JWT Editor
https://jwt.io/
https://github.com/z-bool/Venom-JWT
https://github.com/ticarpi/jwt_tool
https://github.com/wallarm/jwt-secrets
https://github.com/CompassSecurity/jwt-scanner