JWT 是什么
JWT(JSON Web Token)是一种自包含令牌格式:头、载荷、签名三段用点号连接,头与载荷做 Base64Url 编码,签名由服务端用密钥生成。它是 OAuth2、单点登录和前后端分离系统里最常见的会话凭据形态,服务端不查库就能靠签名判断令牌是否被篡改。关键点是:载荷只做编码不做加密,拿到令牌的人都能读出内容,所以 JWT 的配置问题基本等同于会话安全问题。
基本信息
| 结构 | 头(alg/typ)+ 载荷(claims)+ 签名 |
|---|---|
| 常见算法 | HS256 对称密钥;RS256/ES256 非对称密钥 |
| 生命周期字段 | exp 过期、nbf 生效、iat 签发时间 |
| 存放位置 | Authorization 头、Cookie、localStorage |
| 检查前提 | 只分析自有测试账号的令牌,不碰他人凭据 |
典型使用场景
- 评估开始前核对信任模型:谁签发、谁校验、密钥保存在哪一层
- 前后端分离系统的会话全链路走查:登录、刷新、注销三步都要看
- 排查「注销后旧令牌仍可用」这类会话失效不彻底的问题
- 移动端与开放平台接入方的令牌有效期与轮换机制评审
- 修复验证:确认服务端已固定算法、密钥已轮换、有效期已收紧
解析与观察
解析与观察
# 只对自有测试账号的令牌操作;记录字段类型,不记录真实取值
echo '<测试令牌>' | cut -d. -f2 | base64 -d 2>/dev/null | jq .
# 观察载荷:iss/aud/exp/role/uid 是否存在敏感明文
echo '<测试令牌>' | cut -d. -f1 | base64 -d 2>/dev/null
# 观察头:alg 取值与是否声明 typ
date -d @<exp 时间戳> # 把 exp 换算成到期时间,核对是否过长
# 注销后再用同一令牌请求一次只读接口,确认服务端是否已失效该令牌配置项对照
| 检查点 | 风险表现 | 处置方向 |
|---|---|---|
| 算法处理 | 服务端按令牌自称的 alg 校验,含 none | 固定算法白名单,拒绝调用方指定 |
| 密钥强度 | HMAC 密钥为弱口令,可被离线爆破 | 高熵密钥且独立于代码仓库保管 |
| 有效期 | exp 过长或缺失,令牌长期有效 | 短有效期 + 刷新令牌轮换 |
| 撤销机制 | 注销、改密后旧令牌仍可访问 | 标识版本号、黑名单或短有效期组合 |
| 载荷内容 | 载荷放手机号、证件号、角色明文 | 只放标识与必要声明,敏感值另取 |
载荷可读本身不是漏洞:JWT 的设计就是「可读不可改」。只有当签名校验缺失、算法可被指定,或载荷内放了敏感明文时,才构成问题。
对称密钥场景下泄露一份密钥即可伪造任意用户令牌,因此密钥不能出现在前端构建产物、日志与代码仓库中,且各环境必须相互隔离。