文章总结: 本文分析了一个JWT身份验证设计缺陷,问题不在于密码学攻击,而是后端过度信任刷新令牌,将其作为身份的唯一来源。刷新令牌缺乏服务器端会话绑定、令牌标识符(jti)和组织上下文等关键安全控制,导致仅凭令牌即可维持认证状态,形成单点故障。作者通过实验发现,即使删除其他cookie,仅保留刷新令牌仍可访问受保护页面。建议实施令牌轮换、绑定会话状态等防御措施以降低风险。 综合评分: 88 文章分类: 漏洞分析,实战经验,WEB安全,红队,渗透测试
价值 1,450 美元的 JWT 身份验证设计缺陷
Mustafa Mustafa
漏洞集萃
2026年7月8日 11:52 山东
在小说阅读器读本章
去阅读
免责声明 本公众号所发布的文章内容仅供学习与交流使用,禁止用于任何非法用途。
在测试一个私有漏洞赏金计划时,我遇到了一个
作者: Mustafa Adam Gamaraldin Abdalla
原文链接: https://wadgamaraldeen.medium.com/how-i-found-a-critical-jwt-authentication-design-flaw-and-earned-a-1-450-bug-bounty-4ea6bbd90bb5
Introduction
当人们听到“JWT 漏洞”时,他们通常会想到破解的密码学、弱签名秘密或臭名昭著的 alg=none 攻击。
事实上,许多影响最大的 JWT 漏洞与密码学无关。
它们是设计缺陷。
这篇文章描述了我通过错误赏金计划负责任地披露的一个关键身份验证设计缺陷。该问题最终被认为是“严重”,因为它源于一个基本的架构假设:后端将刷新令牌视为用户身份的唯一真实来源。
问题不在于 JWT 可能被破坏。
问题在于它被过于信任了。
Target
出于负责任的披露目的,原始域名已替换为:
https://example.com
初步观察
在查看身份验证流程时,我注意到登录应用程序会生成一个仅 HTTP 刷新令牌。
Cookie:
__Host-refreshToken=<JWT>
到目前为止没有什么异常。
许多现代应用程序使用刷新令牌。
有趣的问题是:
后端真正信任什么?
查看刷新令牌的内部
解码 JWT 会发现一个非常小的有效负载。
{
"sub":"<user_id>",
"iat":1737900000,
"exp":1738500000
}
仅存在三项索赔。
subiatexp
值得注意的是,以下声明不存在:
issaudjti- 组织或租户标识符
- 设备标识符
- 会话标识符
这立即引发了一个架构问题。
如果后端完全从该令牌派生身份验证,那么服务器端会话状态在哪里?
了解身份验证流程
从较高层次来看,身份验证序列如下所示:
User Login
│
▼
Backend authenticates credentials
│
▼
Issues refresh JWT
│
▼
Browser stores __Host-refreshToken
│
▼
Subsequent requests rely on refresh token
如果刷新令牌正确绑定到服务器端状态,那么这是一个完全有效的架构。
下一步是确定这种绑定是否确实存在。
会话验证分析
为了更好地理解身份验证模型,我观察了浏览器会话 cookie 更改时应用程序的行为方式。
该应用程序最初在登录期间发出多个 cookie,包括:
- 刷新令牌
- 会话cookie
- 额外的平台cookie
有选择地删除除刷新令牌之外的所有 cookie 后,应用程序继续将会话视为经过完全身份验证。
受保护的页面仍然可以访问。
没有发生重新验证。
这一观察结果表明,仅刷新令牌就足以维持经过身份验证的状态。
尽管此行为在某些架构中可能是有意为之,但它也表明刷新令牌充当独立的持有者凭证。如果没有额外的服务器端验证,任何未来令牌泄露的影响都会变得更大。
为什么这很重要?
JWT 是经过数字签名的。
如果实施正确,客户端不能简单地修改诸如 sub 之类的声明。
那么实际问题出在哪里呢?
这个问题是建筑性的。
想象一下,在未来的某个时刻,任何弱点都允许为任意身份颁发有效的刷新令牌——例如,通过签名密钥泄露、内部令牌颁发错误或其他可信组件故障。
如果后端仅根据该令牌中包含的 sub 声明来确定身份,则没有其他控制措施来阻止该用户的身份验证。
刷新令牌实际上成为身份的单一事实来源。
当身份验证完全依赖于一个工件时,影响该工件的每一次故障都会变得更加严重。
缺失的安全控制:
刷新令牌缺乏几种常见的防御机制。
– 无服务器端会话绑定
该令牌似乎独立于任何可观察的服务器端会话而存在。
现代身份验证系统通常将刷新令牌与存储的会话元数据相关联,这些元数据可以独立于令牌本身而失效。
– 无令牌标识符 (jti)
没有唯一的令牌标识符:
- 单独的刷新令牌不能轻易被撤销,
- 重用检测变得困难,
- 妥协更难遏制。
– 无组织背景
该令牌仅包含用户标识符。
支持多个组织或租户的应用程序通常受益于将令牌绑定到组织上下文,从而允许在授予访问权限之前进行额外的验证。
– 无刷新令牌轮换
长期刷新令牌通常应在成功使用后轮换。
轮换可以检测重放攻击并限制受损凭据的生命周期。
为什么这是一个设计缺陷
应用程序安全性最重要的区别之一是将实现缺陷与设计缺陷分开。
这个问题不涉及:
- 破解 JWT 密码学,
- 绕过签名验证,
- 利用弱算法。
相反,它是由于对单个经过身份验证的对象过于信任而导致的。
后端假设拥有有效的刷新令牌就足以证明身份,无需额外的上下文或验证。
这种假设造成了单点故障。
说实话 我觉得这完全就是运气,厂商完全可以以无法获取token拒收。。。。
觉得本文内容对您有启发或帮助? 点个关注➕,获取更多深度分析与前沿资讯!
👉 往期精选
逻辑漏洞:邮箱注册 tips #11
非常用403绕过 Tips
一种利用 HTTP 重定向循环的新型 SSRF 技术
邮箱/手机验证绕过
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:漏洞集萃 Mustafa Mustafa《价值 1,450 美元的 JWT 身份验证设计缺陷》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论