文章总结: 本文通过实战案例介绍了一种基于GraphQL接口的未授权漏洞测试方法。作者从删除地址功能点发现/graphql路径,利用introspection查询获取接口结构,通过目录扫描找到console/playground等调试接口,最终成功实现未授权访问。文章指出GraphQL的自描述特性使其成为接口枚举的有效工具,并总结了漏洞的三层问题:introspection未关闭、调试接口暴露和缺乏鉴权机制。 综合评分: 78 文章分类: WEB安全,漏洞分析,实战经验,渗透测试,红队
【项目实战】|从 /graphql 到未授权:另一种Swagger测试思路
Z2O安全攻防
2026年5月13日 21:49 北京
在小说阅读器读本章
去阅读
以下文章来源于隐雾安全 ,作者隐雾安全
隐雾安全 .
隐雾,为您提供职业成功的关键。
📝 编者语
很多人在做接口测试时,第一反应是:
找Swagger文档
但在实际项目中,越来越多的系统开始使用:
- GraphQL
- 内置调试面板(console / playground)
这些东西,本质上就是:
另一种“接口文档”
这篇文章,我们用一个真实案例,走一遍:
从一个功能点 → 找到 GraphQL → 拿到接口结构 → 发现未授权接口
1
GraphQL 和 Swagger 是什么关系?
很多人会把这两个当成完全不同的东西,其实可以这样理解:
🔹 Swagger(传统接口文档)
提前写好接口说明:
- URL
- 参数
- 返回
🔹 GraphQL(动态接口文档)
接口是“自描述”的:
- 可以查询接口结构
- 可以动态拼请求
- 可以直接调试
🧠 核心区别
| | | | — | — | | 类型 | 特点 | | Swagger | 静态文档 | | GraphQL | 可查询的接口结构 |
所以在挖洞时:
GraphQL = 自带“接口枚举能力”的文档系统
2
实战案例(500)
第一步:发现入口
🔍 起点:一个普通功能点
在测试过程中,点到了一个功能:
删除地址
顺手做了一件事
看目录结构
发现一个路径:
/graphql
⚠️ 这个路径意味着什么?
在经验里:
出现 /graphql,基本可以判断:
- 存在 GraphQL 服务
- 可能有调试接口
- 很可能存在接口暴露
第二步:探测 GraphQL 是否可用
接下来就是一个标准动作:
发一个 introspection 查询
📦 请求数据(核心)
{"query":"query IntrospectionQuery{__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}fragment FullType on __Type{kind name description fields(includeDeprecated:true){name description args{...InputValue}type{...TypeRef}isDeprecated deprecationReason}inputFields{...InputValue}interfaces{...TypeRef}enumValues(includeDeprecated:true){name description isDeprecated deprecationReason}possibleTypes{...TypeRef}}fragment InputValue on __InputValue{name description type{...TypeRef}defaultValue}fragment TypeRef on __Type{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name}}}}}}}}"}
🔍 返回结果
如果返回结构信息,比如:
- type
- query
- mutation
👉 就说明:
GraphQL introspection 开启了
📌 这一步的意义
👉 相当于:
拿到了整个接口结构
第三步:目录扫描
对 /graphql 目录进行扫描
🔎 扫描结果
发现多个接口:
/api/graphql/console
/api/graphql/graphql
/api/graphql/graphql-playground
/api/graphql/v1
⚠️ 这些路径意味着什么?
逐个解释👇
路径
作用
console 调试控制台
playground 图形化测试工具
graphql 主接口
v1 版本接口
👉 重点来了:
这些“调试接口”,很多情况下是没有鉴权的
第四步:直接打 console
选择了一个最典型的接口:
POST /api/graphql/console
📦 请求内容
POST /api/graphql/console HTTP/2 {"query":"query IntrospectionQuery{__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}fragment FullType on __Type{kind name description fields(includeDeprecated:true){name description args{...InputValue}type{...TypeRef}isDeprecated deprecationReason}inputFields{...InputValue}interfaces{...TypeRef}enumValues(includeDeprecated:true){name description isDeprecated deprecationReason}possibleTypes{...TypeRef}}fragment InputValue on __InputValue{name description type{...TypeRef}defaultValue}fragment TypeRef on __Type{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name}}}}}}}}"}
🔍 返回结果
成功返回接口结构数据。
⚠️ 这个时候其实已经可以确认:
👉 存在未授权访问
3
总结漏洞本质
如果总结一下,其实是三层问题叠加:
🧩 问题拆解
1️⃣ GraphQL introspection 未关闭
👉 可以直接获取接口结构
2️⃣ 调试接口暴露
👉 console/playground 对外开放
3️⃣ 未做鉴权
👉 任何人都可以访问
📌 最终效果
👉 外部用户可以:
- 枚举接口
- 构造请求
- 直接调用
整个挖掘流程
🧭 挖洞流程
功能点(删除地址)
↓
发现 /graphql
↓
发送 introspection 查询
↓
确认 GraphQL 开启
↓
扫描目录
↓
发现 console / playground
↓
直接访问接口
↓
未授权成功
这个思路可以怎么复用?
这个案例最有价值的,其实不是漏洞本身,而是:
一套可以复用的测试方法
固定动作
现在只要看到这些:
- /graphql
- /api/graphql
- /playground
- /console
做三件事:
1️⃣ 先打 introspection
判断:
👉 能不能拿到 schema
2️⃣ 扫目录
找:
- console
- playground
- 版本接口
3️⃣ 测未授权
直接发请求:
👉 看是否需要登录
一个很重要的认知
做接口测试时,不要局限在:
- 参数
- 权限
- 越权
接口文档本身,就是攻击面
建了个src专项圈子,内容包含src漏洞知识库、src挖掘技巧、src视频教程等,一起学习赚赏金技巧,以及专属微信群一起挖洞
圈子专注于更新src相关:
1、维护更新src专项漏洞知识库,包含原理、挖掘技巧、实战案例2、分享src优质视频课程3、分享src挖掘技巧tips4、小群一起挖洞
图片
图片
图片
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Z2O安全攻防 《【项目实战】|从 /graphql 到未授权:另一种Swagger测试思路》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论