文章总结: 本文通过真实案例展示如何利用GraphQL接口进行安全测试,从发现功能点入手,探测GraphQLintrospection获取接口结构,扫描目录暴露调试接口,最终发现未授权访问漏洞。文章指出GraphQL相当于自带接口枚举能力的文档系统,并总结出可复用的测试方法:发现graphql路径后先查schema,再扫目录找调试接口,最后测未授权。 综合评分: 82 文章分类: 渗透测试,WEB安全,漏洞分析,实战经验,安全工具
【项目实战】另一种Swagger测试思路
迪哥讲事
2026年5月14日 10:00 四川
在小说阅读器读本章
去阅读
以下文章来源于隐雾安全 ,作者隐雾安全
隐雾安全 .
隐雾,为您提供职业成功的关键。
📝 编者语
很多人在做接口测试时,第一反应是:
找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️⃣ 测未授权
直接发请求:
👉 看是否需要登录
一个很重要的认知
做接口测试时,不要局限在:
-
参数
-
权限
-
越权
接口文档本身,就是攻击面
如果你是一个长期主义者,欢迎加入我的知识星球,本星球日日更新,包含号主大量一线实战,全网独一无二,微信识别二维码付费即可加入,如不满意,72 小时内可在 App 内无条件自助退款
往期回顾
#
如何利用ai辅助挖漏洞
#
如何在移动端抓包-下
#
如何绕过签名校验
#
一款bp神器
挖掘有回显ssrf的隐藏payload
ssrf绕过新思路
一个辅助测试ssrf的工具
dom-xss精选文章
年度精选文章
Nuclei权威指南-如何躺赚
漏洞赏金猎人系列-如何测试设置功能IV
漏洞赏金猎人系列-如何测试注册功能以及相关Tips
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:迪哥讲事 《【项目实战】另一种Swagger测试思路》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论