网易首页 > 网易号 > 正文 申请入驻

危险!请马上停止使用JWT!!

0
分享至

JSON Web Tokens,又称JWT。本文将详解:为何JWT不适合存储 Session,以及JWT引发的安全隐患。望各位对JWT有更深的理解!

十分不幸,我发现越来越多的人开始推荐使用 JWT 管理网站的用户会话(Session)。在本文中,我将说明为何这是个非常非常不成熟的想法。

为了避免疑惑和歧义,首先定义一些术语:


  • 无状态 JWT(Stateless JWT):包含Session数据的JWT Token。Session 数据将被直接编码进 Token 内。



  • 有状态 JWT(Stateful JWT):包含Session引用或其ID的JWT Token。Session 数据存储在服务端。



  • Session token(又称 Session cookie):标准的、可被签名的Session ID,例如各类 Web 框架(译者注:包括 Laravel)内已经使用了很久的 Session 机制。Session 数据同样存储在服务端。


需要澄清的是:本文并非挑起「永远不要使用 JWT」的争论 —— 只是想说明 JWT 并不适合作为 Session 机制,且十分危险。JWT 在其它方面的确有其用武之地。本文结尾,我将简短地介绍一些合理用途。

很多人错误地尝试比较CookiesJWT。这种对比毫无意义,就像对比内存和硬盘一样。Cookies 是一种存储机制,然而 JWT Tokens 是被加密并签名后的令牌。

它们并不对立 —— 相反,他们可以独立或结合使用。正确的对比应当是:Session对比JWT,以及Cookies对比Local Storage

在本文中,我将把 JWT Tokens 同 Session 展开对比,并偶尔对比CookieLocal Storage。这样的比较才有意义。

JWT 坊间流传的优势

在人们安利 JWT 时,常常宣扬以下几点好处:










我将会逐条阐述以上观点为何是错误或误导性的,其中部分解释可能会有些模糊,这主要是因为这些「好处」的表述本身就比较模糊。

易于水平扩展?

这是列表中唯一一条在技术层面部分正确的「好处」,但前提是你使用的是无状态 JWT Tokens。然而事实上,几乎没人需要这种横向扩展能力。有很多更简单的拓展方式,除非你在运维像淘宝这样体量的系统,否则根本不需要无状态的会话(Stateless sessions)。

一些扩展有状态会话(Stateful sessions)的例子:


  1. 「在单台服务器上运行多个后端进程」:只需在此服务器上安装 Redis 服务用于存储 Session 即可。



  2. 「运行多台服务器」:只需一台专用的 Redis 服务器用于存储 Session 即可。



  3. 「在多集群内运行多台服务器」:会话保持(又称:粘滞会话)。


以上所有场景在现有软件系统内都具备良好的支持,你的应用需要进行特殊处理的可能性基本为零。

或许你在想,应当为你的应用预留更多调整空间,以防未来需要某些特殊操作。但实践告诉我们,以后再替换 Session 机制并不困难,唯一的代价是,在迁移后所有用户将被强制登出一次。我们没必要在前期实现 JWT,尤其是考虑到它所带来的负面影响。

推荐划水摸鱼神器: https://www.yoodb.com/slack-off/home.html

易于使用?

这个真没有。你不得不自行处理 Session 的管理机制,无论是客户端还是服务端。然而标准的Session cookies则开箱即用,JWT 并没有更简单。

说白了,目前各种开箱即用的框架并没有自动集成 JWT,需要研发人员自行处理。

更加灵活?

我暂时还没看到有人成功地阐述「JWT 如何更加灵活」。几乎每个主流的 Session 实现,都允许你直接把数据存储进 Session,这跟 JWT 的机制并没有差别。据我所知,这只是个流行语罢了。

更加安全?

一大批人认为 JWT Tokens「更加安全」,理由是使用了加密技术。实际上,签名后的 Cookies 比未签名的 Cookies 同样更加安全,但这绝不是 JWT 独有的,优秀的 Session 实现均使用签名后的 Cookies(译者注:例如 Laravel)。

「使用加密技术」并不能神奇地使某些东西更加安全,它必须服务于特定目的,并且是针对该目的的有效解决方案。错误地使用加密反而可能会降低安全性。

另一个我听过很多次的对于「更加安全」的论述是「JWT 不使用 Cookies 传输 Tokens」。这实在是太荒谬了,Cookie 只不过是一条 HTTP 头信息,使用 Cookies 并不会造成任何不安全。事实上,Cookies 受到特别良好的保护,用于防止恶意的客户端代码。

如果担心有人拦截掉你的 Session cookies,那你应当考虑使用 TLS。如果不使用 TLS,任何类型的 Session 机制都可能被拦截,包括 JWT。

内置过期时间功能?

无意义,又没什么卵用的特性。在服务端也能实现过期控制,有不少 Session 实现就是这么做的。实际上,服务端的过期控制更加合理,这样你的应用就可以清除不再需要的 Session 数据;若使用无状态 JWT Tokens 且依赖于它的过期机制,则无法执行此操作。

这个过期时间在某些场景实际上是增加了复杂度的。

无需询问用户「本网站使用 Cookies」?

完全错误。并没有什么「Cookies 法律」—— 有关 Cookies 的各种法律实际上涵盖了任何类型「对某项服务的正常运行非严格必须的持久性 ID」,任何你能想到的 Session 机制都包括在内。

译者注:然鹅中国并没有。

简单来说:


  • 若出于系统功能目的使用 Session 或 Token(例如:保持用户的登录态),那么无论怎样存储 Session 均无需征得用户同意。



  • 若出于其他目的使用 Session 或 Token(例如:数据分析、追踪),那么无论怎样存储 Session 都需要询问用户是否允许。


防止 CSRF 攻击?

这个真真的没有。存储 JWT Tokens 的方式大概有两种:


  • 「存入 Cookie」:仍然易受 CSRF 攻击,还是需要进行特殊处理,保护其不受攻击。



  • 「其他地方,例如 Local Storage」:虽然不易受到 CSRF 攻击,但你的网站需要 JavaScript 才能正常访问;并且又引发了另一个完全不同,或许更加严重的漏洞。我将在后文详细说明。


预防 CSRF 攻击唯一的正确方法,就是使用 CSRF Tokens。Session 机制与此无关。

更适用于移动端?

毫无根据。目前所有可用的浏览器几乎都支持 Cookies,因此也支持 Session。同样,主流的移动端开发框架以及严谨的 HTTP 客户端库都是如此。这根本不是个问题。

适用于阻止 Cookies 的用户?

不太可能。用户通常会阻止任何意义上的持久化数据,而不是只禁止 Cookies。例如,Local Storage 以及任何能够持久化 Session 的存储机制(无论是否使用 JWT)。不管你出于多么简单的目的使用 JWT 都无济于事,这是另一个完全独立的问题了。另外,试图让身份认证过程在没有 Cookies 的情况下正常进行,基本没戏。

最重要的是,禁用掉所有 Cookies 的多数用户都明白这会导致身份认证无法使用,他们会单独解锁那些他们比较关心的站点。这并不是你 —— 一个 Web 开发者应当解决的问题。更好的方案是,向你的用户们详细地解释为何你的网站需要 Cookies 才能使用。

JWT 的劣势

以上,我已经对常见的误解做了说明,以及为什么它们是错误的。你或许在想:「这好像也没什么大不了的,即便 JWT 无法带来任何好处,但也不会造成什么影响」,那你真是大错特错了。

使用 JWT 作为 Session 机制存在很多缺点,其中一部分会造成严重的安全问题。

更费空间

JWT Tokens 实际上并不「小」。尤其是使用无状态 JWT 时,所有的数据将会被直接编码进 Tokens 内,很快将会超过 Cookies 或 URL 的长度限制。你可能在想将它们存储到 Local Storage,然而...

更不安全

若将 JWT Tokens 存储到 Cookies 内,那么安全性与其他 Session 机制无异。但如果你将 JWT 存储至其它地方,会导致一个新的漏洞,详见https://blog.prevoty.com/does-jwt-put-your-web-app-at-risk,尤其是「Storing sessions」这一部分。

Local Storage,一个 HTML5 内很棒的功能,使浏览器支持 Key/Value 存储。所以我们应当将 JWT Tokens 存储到 Local Storage 吗?考虑到这些 Tokens 可能越来越大,或许会很有用。Cookies 通常在 4k 左右的存储时比较占优势,对于较大的 Tokens,Cookies 可能无法胜任,而 Local Storage 或许成了明确的解决方案。然而,Local Storage 并没有提供任何类似 Cookies 的安全措施。 LocalStorage 与 Cookies 不同,并不会在每次请求时发送存储的数据。获取数据的唯一方法是使用 JavaScript,这意味着任何攻击者注入的 JavaScript 脚本只需通过内容安全策略检查,就能任意访问或泄露数据。不光是这样,JavaScript 并不在意或追踪数据是否通过 HTTPS 发送。 就 JavaScript 而言,它就只是个数据而已,浏览器会像操作其它数据一样来处理它。在历代工程师们经历了各种麻烦之后,终于能够确保没有人可以恶意接触到我们的 Cookies,然而我们却试图忽略这些经验。这对我来说似乎是在退步。

简单来说,「使用 Cookies 并不是可选的」,无论你是否采用 JWT。

无法单独销毁

还有更多安全问题。不像 Sessions 无论何时都可以单独地在服务端销毁。无状态 JWT Tokens 无法被单独的销毁。根据 JWT 的设计,无论怎样 Tokens 在过期前将会一直保持有效。举个例子,这意味着在检测到攻击时,你却不能销毁攻击者的 Session。同样,在用户修改密码后,也无法销毁旧的 Sessions。

对此,我们几乎无能为力,除非重新构建复杂且有状态(Stateful)的基础设施来明确地检测或拒绝特定 Session,否则将无法结束会话。但这完全违背了使用无状态JWTTokens的最初目的。面试宝典:https://www.yoodb.com/

数据延迟

与上文的安全问题类似,还有另一个潜在的安全隐患。就像缓存,在无状态 Tokens 内存储的数据最终会「过时」,不再反映数据库内最新的数据。

这意味着,Tokens 内保留的可能是过期的信息,例如:用户在个人信息页面修改过的旧 URL。更严肃点讲,也可能是个具备admin权限的 Token,即使你已经废除了admin权限。因为无法销毁这些 Tokens,所以面对需要移除的管理员权限,除非关闭整个系统,别无他法。

实现库缺乏生产环境验证或压根不存在

你或许在想,以上的这些问题都是围绕着「无状态 JWT」展开的,这种说法大部分情况是对的。然而,使用有状态 Tokens 与传统的 Session cookies 基本上是等效的... 但却缺乏生产环境的大量验证。

现存的 Session 实现(例如适用于 Express 的 express-sessionhttps://github.com/expressjs/sessio)已经被用于生产环境很多很多年,它们的安全性也经过了大量的改良。倘若使用 JWT 作为 Session cookies 的临时替代品,你将无法享受到这些好处,并且必须不断改进自己的实现(在此过程中很容易引入漏洞),或使用第三方的实现,尽管还没有在真实世界里大量应用。

译者注:实际上,Laravel Passport 便是使用类似「有状态 JWT」的方式来存储 OAuth Access Token。幸运的是,Passport 已经有不少实际应用,且不完全依赖于 JWT。
结论

无状态 JWT Tokens 无法被单独地销毁或更新,取决于你如何存储,可能还会导致长度问题、安全隐患。有状态 JWT Tokens 在功能方面与 Session cookies 无异,但缺乏生产环境的验证、经过大量 Review 的实现,以及良好的客户端支持。

除非,你工作在像 BAT 那样规模的公司,否则没什么使用 JWT 作为 Session 机制的理由。还是直接用 Session 吧。

所以... JWT 适合做什么?

在本文之初,我就提到 JWT 虽然不适合作为 Session 机制,但在其它方面的确有它的用武之地。该主张依旧成立,JWT 特别有效的使用例子通常是作为一次性的授权令牌。

引用JSON Web Token specification(https://tools.ietf.org/html/rfc7519):

JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. [...] enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.

在此上下文中,「Claim」可能是一条「命令」,一次性的认证,或是基本上能够用以下句子描述的任何情况:

你好,服务器 B,服务器 A 告诉我我可以 < ...Claim... >,这是我的证据:< ...密钥... >。

举个例子,你有个文件服务,用户必须认证后才能下载文件,但文件本身存储在一台完全分离且无状态的「下载服务器」内。在这种情况下,你可能想要「应用服务器(服务器A)」颁发一次性的「下载Tokens」,用户能够使用它去「下载服务器(服务器B)」获取需要的文件。springboot系列教程:https://www.yoodb.com/spring/springboot/integration-flyway.html

以这种方式使用 JWT,具备几个明确的特性:


  • Tokens 生命期较短。它们只需在几分钟内可用,让客户端能够开始下载。



  • Tokens 仅单次使用。应用服务器应当在每次下载时颁发新的 Token。所以任何 Token 只用于一次请求就会被抛弃,不存在任何持久化的状态。



  • 应用服务器依旧使用 Sessions。仅仅下载服务器使用 Tokens 来授权每次下载,因为它不需要任何持久化状态。


正如以上你所看到的,结合 Sessions 和 JWT Tokens 有理有据。它们分别拥有各自的目的,有时候你需要两者一起使用。只是不要把 JWT 用作「持久的、长期的」数据就好。

作者:Wi1dcard 译文:https://learnku.com/articles/22616 原文:http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!

特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注

文章有帮助的话,点在看,转发吧!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
无证倒卖香烟案引行政诉讼:收回专卖许可是否送达本人?烟草局承认3年后补贴通知

无证倒卖香烟案引行政诉讼:收回专卖许可是否送达本人?烟草局承认3年后补贴通知

红星新闻
2024-06-13 22:58:18
大瓜!黄一鸣撕葱事件新进展,王思聪连夜改名,女方出大招!

大瓜!黄一鸣撕葱事件新进展,王思聪连夜改名,女方出大招!

娱记掌门
2024-06-15 23:34:57
喝茶对心脏到底是好是坏?医生苦劝:4种茶,一口都不要喝

喝茶对心脏到底是好是坏?医生苦劝:4种茶,一口都不要喝

宋若讲故事
2023-01-18 21:38:26
终于出手了!严惩3大叛徒,永不恢复中国籍!

终于出手了!严惩3大叛徒,永不恢复中国籍!

星辰故事屋
2024-06-15 17:35:32
专家:对俄战争已然失败

专家:对俄战争已然失败

俄罗斯卫星通讯社
2024-01-22 15:13:11
一名美国签证官写给中国拒签者的信:我不会无故拒签一个人

一名美国签证官写给中国拒签者的信:我不会无故拒签一个人

小刀99
2024-06-13 20:24:25
大瓜!又有网友自曝给王思聪生孩子,称万达长孙,喊话不想再忍了

大瓜!又有网友自曝给王思聪生孩子,称万达长孙,喊话不想再忍了

拾娱先生
2024-06-15 22:05:08
马龙回应无缘奥运单打:以自己目前能力和状态,可能有点吃力

马龙回应无缘奥运单打:以自己目前能力和状态,可能有点吃力

懂球帝
2024-06-15 12:58:10
一单亲妈妈穿“露奶装”送娃上学,男家长:光着整个脊背成何体统

一单亲妈妈穿“露奶装”送娃上学,男家长:光着整个脊背成何体统

知秋侃史
2024-06-12 04:14:35
“非夫妻”的男女开房,若只登记1人信息,被警察查房有啥后果?

“非夫妻”的男女开房,若只登记1人信息,被警察查房有啥后果?

105度的世界
2024-06-13 10:32:14
路易小王子随风笛声起舞,姐姐夏洛特试图阻止,妈妈凯特笑而不语

路易小王子随风笛声起舞,姐姐夏洛特试图阻止,妈妈凯特笑而不语

译言
2024-06-15 20:26:17
河南64岁大爷五年间染指55名女性,只因太了解女性心理

河南64岁大爷五年间染指55名女性,只因太了解女性心理

真实故事汇
2024-05-06 13:31:30
缅北女魔头魏榕怪癖,活剥“肉灵芝”是小事,最恐怖的是“驴耳”

缅北女魔头魏榕怪癖,活剥“肉灵芝”是小事,最恐怖的是“驴耳”

马尔科故事会
2024-06-15 11:10:21
股民柯某在股价从23元跌到1.2元抄底608万股,却连续16个跌停退市

股民柯某在股价从23元跌到1.2元抄底608万股,却连续16个跌停退市

惜别的海岸
2024-06-15 16:17:43
初二女儿端午节轻生,父亲看着两箱试卷痛哭:我知道问题所在了!

初二女儿端午节轻生,父亲看着两箱试卷痛哭:我知道问题所在了!

青栀伊人
2024-06-15 22:00:45
38岁已婚女与37岁情人,在石凳子上发生关系,温存后被残忍杀害

38岁已婚女与37岁情人,在石凳子上发生关系,温存后被残忍杀害

胖胖侃咖
2024-06-08 08:00:08
江苏考生用了一下橡皮,监考老师直接叫来武警,一查多人被判刑

江苏考生用了一下橡皮,监考老师直接叫来武警,一查多人被判刑

老黑谈历史
2024-06-14 10:17:25
极致黑丝诱惑 | Alexander Wang 2025早春度假系列

极致黑丝诱惑 | Alexander Wang 2025早春度假系列

CFW服装设计
2024-06-12 17:37:29
传华东政法毕业生就业难!校友会发出倡议渡难关,张雪峰失算了?

传华东政法毕业生就业难!校友会发出倡议渡难关,张雪峰失算了?

火山诗话
2024-06-13 09:12:39
姜萍父亲发声,家庭困难住着破房子,姐妹都是学霸,刘奔搞笑回应

姜萍父亲发声,家庭困难住着破房子,姐妹都是学霸,刘奔搞笑回应

娱乐圈见解说
2024-06-15 18:57:27
2024-06-16 06:24:49
Java精选
Java精选
一场永远也演不完的戏
1551文章数 3855关注度
往期回顾 全部

科技要闻

TikTok开始找退路了?

头条要闻

欧洲杯-23秒丢球破纪录 意大利2-1逆转阿尔巴尼亚

头条要闻

欧洲杯-23秒丢球破纪录 意大利2-1逆转阿尔巴尼亚

体育要闻

莱夫利,让困难为我让路

娱乐要闻

江宏杰秀儿女刺青,不怕刺激福原爱?

财经要闻

新情况!高层对人民币的态度180°转弯

汽车要闻

东风奕派eπ008售21.66万元 冰箱彩电都配齐

态度原创

数码
艺术
本地
教育
家居

数码要闻

低至 5747 元,爱普生 CH-TW6280T 真 4K 投影仪京东大促

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

本地新闻

粽情一夏|海河龙舟赛,竟然成了外国人的大party!

教育要闻

情侣高考后办订婚宴后续,当事人回应原因,网友:升学宴还办吗?

家居要闻

空谷来音 朴素留白的侘寂之美

无障碍浏览 进入关怀版