关于JWT鉴权安全问题

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: JSON Web Token(JWT https://jwt.io )是一种跨域身份验证解决方案,其主要认证原理是提供一个可信签名,利用存在客户端的secret_key将明文的鉴权数据做一个签名,用于跨域校验权限的合法性。

什么是JWT

aaa

JSON Web Token(JWT  https://jwt.io )是一种跨域身份验证解决方案,其主要认证原理是提供一个可信签名,利用存在客户端的secret_key将明文的鉴权数据做一个签名,用于跨域校验权限的合法性。

举一个例子:

Authorizatione: yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4ifQ.MXi3JVNa96zFigIouJL9dSmGxXmLkyO2lMyiJpw-sEs
1

https://jwt.io生成

JWT分为三段,由"."分开,第一段是加密算法,这里选择的是HS256,也就是基于SHA-256的HMAC,对称加密签名算法,介于安全性,其实用RS256(基于SHA-256的RSA256,非对称加密签名算法)更好,原因后面会提到。第二段是内容,这里就是给用户标上了admin的标签,在用jwt时,切记勿将敏感数据直接存入JWT,因为JWT本身只提供签名认证作用,其数据还是明文传输,任何人拿到都可以解密,并不能起到保密作用。

echo eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 | base64 --d
{"alg":"HS256","typ":"JWT"}
echo eyJ1c2VyIjoiYWRtaW4ifQ== | base64 --d
{"user":"admin"}

第三段就是加密签名内容了,客户端在接收到用户端传输过来的JWT后,会首先利用secret_key校验签名,如果签名正确,就会去解密第二段的内容,用于认证。

关于JWT的安全性

用JWT代替cookie做站点鉴权,对多个业务方共享一套账户体系的确带来了很大的便利,相互获取数据不用考虑带cookie跨域导致的一系列安全风险(例如JSONP、CORS等)也不用在交互身份信息时每次都实现一次OAUTH,对开发和安全有极大的帮助,但是由于JWT的安全性全部依赖与最后的签名,其实还是有安全风险的,下面分别说下自己遇到过的几个JWT伪造攻击成功的例子。
1、测试站点与主站点secret_key相同
之前在挖掘漏洞的时候遇到过,某需要拿下来的后台main.xxx.com,存在一个测试站点dev.xxx.com,两个站点可能功能存在部分不同,但都是利用JWT鉴权,并且main.xxx.com登陆存在验证码,而dev.xxx.com不用验证码可以爆破,于是我尝试爆破了dev.xxx.com。

发现存在弱口令 :

123456 / xxxxxxxxx

2

登陆成功后发现返回了一段token,是JWT。并且发现在之后请求数据的数据包里,是利用此段JWT鉴权。

3

 于是猜想,main.xxx.com与dev.xxx.com有没有可能存在是利用的同一段secret_key,这样我就能利用这段JWT去登陆main.xxx.com主站系统,burpsuite修改返回包为测试站点登陆成功的返回包:

4

直接登陆成功main.xxx.com:

5

这里,我们引出了一个安全隐患:对于不同的站点,JWT的secret_key不能设置为相同。
2、泄露secret_key导致任意用户登录

在很多开发框架里面,对DEBUG模式下的异常处理,都会将一些配置信息显示出来,以便于开发者调试,例如Django的调试页面:

6

来源:fofa.so

有的开发过程中,如果是自己实现的JWT,可能会将secret_key存在配置信息中,在部分框架的报错页面中,会导致secret_key泄漏,最后导致任意用户伪造登陆,例如hackerone上面最近披露的一个漏洞:

https://hackerone.com/reports/460545
图片.png

我在之前测试中也遇到过,当时是遇到一个利用JWT鉴权的框架开发的APP下找到一个Debug页面,发现secret_key直接回显在了Debug页面前端:

7

这样,我们可以利用低权限用户的JWT,去伪造高权限的JWT,具体方法如下:

base64 decode原本JWT的加密算法与JWT内容

伪造自己想伪造的内容部分

利用泄漏的secret_key对伪造的内容进行签名

8

利用得到的JWT字符串,直接用管理员权限登陆了刚刚的系统。

 当然,不止是DEBUG页面,类似泄漏的方法很多,例如Flask模板注入、格式化字符串漏洞可以直接读取配置信息、配置文件在WEB目录下可下载、CMS默认存在secret_key使用未修改等,这里就不一一叙述了。

对于secret_key泄漏情况,其实JWT本身设计的时候是有考虑到的,就是之前提到的JWT会提供不同的签名算法,其中说到了RS256算法会更好,其原因就是RS256(采用SHA-256 的 RSA签名)是一种非对称算法,它使用公共/私钥对: 标识提供方采用私钥生成签名, JWT 的使用方获取公钥以验证签名。也就是说,我们这里只需要维护一个私钥服务用于保护私钥,而用于验证签名的公钥就可以分发到下面各个业务方,就算他们配置不当,将公钥泄漏,也无法通过公钥对我们的JWT认证系统伪造。

3、secret_key过弱,或者长期不更换导致可爆破

之前提到过,JWT有一个缺陷是无法对数据进行加密,也就是说数据是对用户都是明文可知的,这就出现一个问题:

既然需要加密的数据、算法我都知道,为什么不能考虑爆破密钥?

所以过弱的密钥肯定是很容易被爆破成功的,毕竟是签名算法,爆破是否成功也无需传入服务端进行校验,能否爆破成功完全在于本地主机的算力大小。有人可能就会想着,那设置一个较长、随机的强key就行了。

但实际情况是随着现在超算的发展,算力越来越强的情况下,只要secret_key一直能保持不变,就肯定是能在本地被算出来,只不过是一个成本大小的问题,有没有人愿意为了你的数据,去付出这样的成本。

当然,最后这一点只是一个经验猜想之谈,我也没有实际上去操作过,也没有例子可以说明,大家可以自己尝试,说不定就真的能爆破成功~。

利用JWT认证的安全建议

严格保护自己的secret_key,防止泄漏

禁止线上站点与测试站点用一套JWT

利用RS算法代替HS算法

线上环境一定要禁止debug

设置较强的secret_key,并且定期更换
相关文章
|
6月前
|
JSON JavaScript 数据格式
jwt-auth插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能。
jwt-auth插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能。
163 1
|
5天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
18 1
|
5月前
|
存储 缓存 数据库
【万字长文】微服务整合Shiro+Jwt,源码分析鉴权实战
介绍如何整合Spring Boot、Shiro和Jwt,以实现一个支持RBAC的无状态认证系统。通过生成JWT token,实现用户无状态登录,并能根据用户角色动态鉴权,而非使用Shiro提供的注解,将角色和权限信息硬编码。此外,文章还探讨了如何对Shiro的异常进行统一捕获和处理。作为应届生,笔者在学习Shiro的过程中进行了一些源码分析,尽管可能存在不足和Bug,但希望能为同样需要实现权限管理的开发者提供参考,并欢迎各位大佬指正完善。
345 65
【万字长文】微服务整合Shiro+Jwt,源码分析鉴权实战
|
3月前
|
JSON 数据安全/隐私保护 数据格式
Nest.js 实战 (八):基于 JWT 的路由身份认证鉴权
这篇文章介绍了身份验证的重要性和多种处理策略,重点放在了JWT(JSON Web Token)认证在Nest.js框架中的应用。文章包含了JWT认证的流程,如何在Nest.js中实现,以及如何创建JWT认证策略。包括了安装依赖,创建处理认证流程的文件,以及如何使用HttpException过滤器来处理未登录访问。
194 0
Nest.js 实战 (八):基于 JWT 的路由身份认证鉴权
|
3月前
|
NoSQL 安全 Java
Java Spring Boot中使用Shiro、JWT和Redis实现用户登录鉴权
Java Spring Boot中使用Shiro、JWT和Redis实现用户登录鉴权
|
5月前
|
存储 JSON API
在django3应用中使用现代的JWT鉴权
【6月更文挑战第8天】本文介绍流行的鉴权方式,JSON Web Tokens (JWT) 是一种验证JSON数据所有者的机制,它是一个编码的、安全的字符串,包含可信任的数据且能加密签名。无状态的令牌认证允许客户端存储令牌并将其在每次请求。
63 8
在django3应用中使用现代的JWT鉴权
|
3月前
|
关系型数据库 API Go
[golang]在Gin框架中使用JWT鉴权
[golang]在Gin框架中使用JWT鉴权
104 0
|
6月前
|
负载均衡 Cloud Native 安全
云原生最佳实践系列 6:MSE 云原生网关使用 JWT 进行认证鉴权
本文档介绍了如何在 MSE(Microservices Engine)云原生网关中集成JWT进行全局认证鉴权。
1010 15
|
6月前
|
JSON JavaScript 数据格式
jwt-auth插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能
jwt-auth插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能
133 1