文章总结: 文章详细介绍了JWT越权漏洞的实战测试过程,包括修改role字段实现权限提升、算法混淆降级、kid参数注入等攻击手法,分析了漏洞成因如开发框架默认不安全、微服务架构放大问题、AI辅助开发副作用,并给出了系统挖掘方法和防御建议,强调权限应放回服务端验证。 综合评分: 85 文章分类: 渗透测试,漏洞分析,WEB安全,安全建设
改了JWT里的role字段,我直接从普通用户变成了管理员
原创
KLSEC KLSEC
昆仑AI安全实验室
2026年9月4日 00:17 广东
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
2026年9月2日,我在测一个刚拿了A轮融资的SaaS平台。登录后,Burp自动捕获了请求头里的JWT。我把token解码,payload里明晃晃写着:
{ "sub": "user_88421", "role": "user", "exp": 1768345200}
我用在线JWT编辑工具把role改成了admin,重新编码。然后把改过的token塞回请求头,重放。响应返回了只有管理员才能看的全站用户列表。
后端没有验签,或者说,它压根没检查签名。它只看了payload里的role字段。
那一刻我意识到:2026年了,JWT的角色提升漏洞依然遍地都是。
一、JWT为什么总在这种地方翻车?
JWT的结构很简单:Header.Payload.Signature。Header声明算法,Payload放数据,Signature用来防篡改。
问题出在后端对JWT的处理逻辑上。一个正确的JWT验证流程应该是:
- 用服务端保存的密钥验证签名,确保token没被篡改。
- 从token里提取用户标识(如
sub或user_id)。 - 根据这个标识去数据库查用户的真实权限。
- 数据库返回的角色信息决定用户能干什么。
但大量开发团队简化了后两步。他们要么省略了签名验证,要么信任了payload里的role字段,要么两者都做了——但做得不彻底。
我见过最离谱的情况是:服务端验证了签名,但验证完就把payload里的role当成真实权限了。攻击者不用伪造签名,只需要找到一个签名有效但role字段可以被“合法修改”的漏洞——比如通过注册接口可以传入自定义role值,或者通过算法混淆把RS256降级成HS256然后自己签名。
但更常见的还是最简单的那种:完全不验签。
二、2026年JWT越权的新形态
除了经典的不验签直接改role,今年我还发现了几个值得说的新玩法。
1. 算法混淆降级
有些服务端的JWT验证库配置错误,同时接受RS256和HS256。攻击者把Header里的alg从RS256改成HS256,然后用服务端的RSA公钥(通常是公开的)作为HMAC密钥,自己签名一个role=admin的token。服务端用HS256验证,用的是公钥,验证通过。攻击者成了admin。
2. kid参数注入
JWT Header里有个kid参数,用来指定验证时用哪把密钥。如果服务端逻辑是“从文件系统按kid路径读密钥”,攻击者可以传kid=../../dev/null,让验证过程找不到密钥而返回true。
3. alg=none
有些开发库允许alg=none,即不签名。攻击者把alg改成none,去掉签名部分,服务端照单全收。这个漏洞太老了,现在不太常见,但在老系统里偶尔还能遇到。
4. 过期时间篡改
exp字段可以改。有些服务端不校验exp,或者校验不严格。攻击者把过期时间改成未来几十年,一个本应过期的token又活了。
5. JWT里的数组越权
有些开发者会在JWT里放roles: ["user"]。如果后端判断逻辑是if ("admin" in roles),攻击者把roles改成["user","admin"],后端看到admin在数组里,就给了管理员权限。
三、实战:从普通用户到域管理员的完整链路
以下是一次脱敏的实战测试。
目标: 某云原生SaaS,后端Go语言,微服务架构,API网关统一鉴权,权限基于JWT中的role字段。
第一步:正常登录,获取JWT
POST /api/v1/auth/login{"username":"testuser","password":"Test@123"}
响应:{ "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzg4NDIxIiwicm9sZSI6InVzZXIiLCJleHAiOjE3NjgzNDUyMDB9.signed_part"}
第二步:解码payload
用Burp的JWT Editor插件或在线工具解码:
{ "sub": "user_88421", "role": "user", "exp": 1768345200}
role是user。
第三步:修改role
把role改成admin,重新编码。这里我没有签名——因为我要先测试“不验签”的情况。
第四步:重放请求
把改过的token放到Authorization: Bearer头里,请求管理员接口:
GET /api/v1/admin/usersAuthorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzg4NDIxIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNzY4MzQ1MjAwfQ.unsigned
响应返回了200,body里是所有用户列表。管理员接口越权成功。
第五步:测试签名验证
为了确认服务端是否验签,我故意把token的签名部分改成一个随机字符串,重放。响应仍然200。说明服务端完全没有验签。
第六步:扩大战果
确认了role字段的有效性后,我进一步测试了其他接口:
GET /api/v1/admin/config:系统配置,含数据库连接串。PUT /api/v1/admin/user/role:修改任意用户角色。POST /api/v1/admin/billing:财务数据。
全部越权成功。这个漏洞从发现到拿下全站数据,只用了15分钟。高危,赏金上万元。
四、为什么2026年还有这么多JWT越权?
- 开发框架的默认不安全。 很多教程和脚手架项目在演示JWT时,都只讲了“如何生成和解析”,没讲“如何正确验签”和“权限如何读取”。开发者照着写,就把
role写进了token,并在后端直接读取。 - 微服务架构放大了问题。 在微服务里,API网关验完签,把token转给内部服务。内部服务之间相互信任,有的内部服务就不再验签,直接读payload。攻击者绕到内部服务就能越权。
- AI辅助开发的副作用。 今年AI生成代码的量暴增。AI生成的JWT代码往往“能跑通就行”,缺少安全细节。开发者用AI写出来,不审计,直接上线。
五、怎么系统挖掘JWT越权漏洞?
工具:
- Burp Suite + JWT Editor插件
- jwt_tool(Python)
- 在线JWT解码器(如jwt.io)
流程:
- 登录后,从请求头或Cookie里提取JWT。
- 用JWT Editor插件解码payload,看是否包含
role、roles、admin、userType等权限相关字段。 - 尝试修改这些字段,重新编码(先不签名,或者用None算法)。
- 重放请求,观察响应是否越权成功。
- 如果修改后无效,再测试算法混淆(RS256→HS256)、
kid注入等高级手法。 - 如果找到越权,继续扩大战果,测试所有管理员接口。
注意:
- 修改JWT时,先备份原始token,避免影响后续测试。
- 测试
alg=none时,有些服务端会报错,这是正常的。 - 如果服务端使用了强签名,先尝试从JS文件、报错信息、配置文件里找密钥。很多密钥硬编码在前端JS里。
六、防御:把权限的“真身”放回服务端
- 强制验签。 无论微服务怎么拆,每个服务在读取JWT前都必须验证签名。签名密钥必须安全保存,不得硬编码在代码或前端。
- 权限不放在JWT里。 JWT里只放用户标识(如
sub),不写role、permissions等敏感字段。后端根据用户标识从数据库或缓存中读取真实权限。这样即使JWT被篡改,也只能改到一个不存在的用户,权限无法被伪造。 - 禁用算法混淆。 服务端验证JWT时,明确指定允许的算法(如只允许RS256)。如果使用对称算法,确保证书和密钥管理正确。
- 短有效期和轮换。 JWT有效期控制在15分钟到1小时,配合Refresh Token机制。密钥定期轮换。
- 审计日志。 记录所有JWT验证失败和权限变更事件,异常时及时告警。
七、写在最后
JWT是Web安全里绕不开的一课,也是最容易踩坑的一课。它的设计初衷是好的——无状态、可扩展、跨域。但开发者对它的理解往往停留在“能用就行”,忘了“安全地实现”才是核心。
2026年,JSON Web Token已经成了AI时代的默认认证方式之一。但JWT越权漏洞,尤其是“信任payload里的role字段”这种低级错误,依然在各大SRC里反复出现。每次我测一个目标,都会习惯性地把JWT解码看看里面写了什么。十次里总有一两次,role字段就那么赤裸裸地躺在那儿,等着被我改成admin。
下次挖洞时,别只盯着SQL注入和XSS。打开你的JWT解码器,看看payload里有没有role。如果有,改一下试试。你可能就解锁了管理员视角。
严正声明 本文所述技术仅用于合法授权的安全测试。所有案例均已脱敏处理。利用JWT越权漏洞进行未授权操作属于违法行为,与作者无关。请在SRC平台授权范围内进行测试,遵守法律法规。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:昆仑AI安全实验室 KLSEC KLSEC《改了JWT里的role字段,我直接从普通用户变成了管理员》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。



![[BSidesCF2020]Hadabadday](/images/random/titlepic/10.jpg)






评论