文章总结: 文档分析了一个GraphQL接口中因Mutation别名数量未受限制导致的DoS漏洞。攻击者可在单次请求中重复添加高耗时操作的别名,使服务器依次执行这些操作,耗尽CPU或线程池资源,导致服务响应缓慢或超时。关键发现包括利用verifyAccountRecoveryPhoneNumber这一验证手机号的接口,通过别名叠加可使响应时间从8秒延长至29秒并触发500错误。建议实施别名数量限制和操作去重机制以缓解风险。 综合评分: 85 文章分类: 漏洞分析,WEB安全,安全开发,实战经验,解决方案
GraphQL 接口 Mutation别名导致的Hackerone DoS 漏洞
原创
Pwn1 Pwn1
漏洞集萃
2026年4月27日 14:11 山东
在小说阅读器读本章
去阅读
免责声明 本公众号所发布的文章内容仅供学习与交流使用,禁止用于任何非法用途。
在测试一个私有漏洞赏金计划时,我遇到了一个
总结
这是一个存在于 GraphQL API 中的DoS漏洞。
核心问题在于系统没有对单次请求里的 Mutation 别名(数量做严格的安全限制)。
只要在请求里疯狂叠加同一个高耗时操作的别名,服务器就会老老实实地排队挨个处理。这会导致服务器后端资源(如 CPU 或线程池)被严重挤占,正常服务响应变得极度缓慢甚至直接报错超时。
漏洞场景
这个漏洞发生在账号安全设置的业务场景里。具体来说,是在设置或验证用于账号恢复的手机号时触发的。对应的核心端点是 /graphql,调用的底层接口是用来验证手机验证码的 verifyAccountRecoveryPhoneNumber。
原本功能流程
给不太熟悉这块业务的大佬科普一下,按道理来讲,正常不带恶意攻击时,这个功能是这么一步步运作的:
用户在前端的安全设置页面输入需要绑定的恢复手机号,系统发送一条短信验证码。接着,用户把收到的验证码填进输入框并点击提交,前端随之会往后端的 /graphql 端点发送一个包含 verifyAccountRecoveryPhoneNumber 这一 Mutation 的 POST 请求,同时把 verification_code 和 otp_code 作为参数传过去。
服务器端收到数据后,会去数据库或者缓存服务里核对验证码的正确性,最后返回验证成功或失败的结果。由于这单次验证可能涉及复杂的校验逻辑或者与外部通信,所以它本身就是一个比较耗时的操作,单次正常请求的响应时间大概在 8 秒左右。
发现过程
最开始盯上这个点,是因为在拦截正常的手机号验证请求包并重放时,敏锐地注意到单次调用的响应时间特别长(将近 8 秒钟)。在这种高耗时接口面前,自然会想到:如果让服务器同时处理多个一模一样的请求会怎么样?是不是能把服务器卡死?
但是,如果在网络层直接使用多线程并发发包,很可能会被系统前端或网关层的速率限制机制给拦截下来。为了绕过常规的并发限制,测试思路转向了 GraphQL 自身的天然特性——别名功能。
既然单次操作耗时 8 秒,那就在同一个 JSON Payload 里面,利用别名把 verifyAccountRecoveryPhoneNumber 这个耗时的 Mutation 复制多份,比如命名为 verify1、verify2、verify3。构造好请求发过去之后,效果立竿见影。响应时间开始随着别名的数量线性飙升。
增加一个别名,耗时直接翻倍变成 16 秒;继续叠加,塞入 4 个别名同时发过去,服务器直接就扛不住了,耗时拉长到了 25 到 29 秒,并且由于处理时间过长,网关直接返回了 500 Internal Server Error 或者是超时报错。这足以证明服务端正在毫无防备地、依次执行这些极其耗费资源的操作。
POST /graphql HTTP/2
Host:
Cookie: █████████
Content-Type: application/json
X-Csrf-Token: █████████
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Content-Length: 417
{"query":"mutation VerifyAccountRecoveryPhoneNumberMutations(verificationcode:String!,otp_code: String) {\n verify1: verifyAccountRecoveryPhoneNumber(input: { verification_code: verificationcode,otpcode:otp_code }) {\n __typename\n me {\n name\n }\n }\n}","variables":{"product_area":"other","product_feature":"other","otp_code":"███████","verification_code":"██████"}}
mutation VerifyAccountRecoveryPhoneNumberMutations(verificationcode:String!,otp_code: String) {
verify1: verifyAccountRecoveryPhoneNumber(input: { verification_code: verificationcode,otpcode:otp_code }) {
__typename
me {
}
}
verify2: verifyAccountRecoveryPhoneNumber(input: { verification_code: verificationcode,otpcode:otp_code }) {
__typename
}
verify3: verifyAccountRecoveryPhoneNumber(input: { verification_code: verificationcode,otpcode:otp_code }) {
__typename
}
}
}
来源:
https://hackerone.com/reports/3287208
觉得本文内容对您有启发或帮助? 点个关注➕,获取更多深度分析与前沿资讯!
👉 往期精选
一种利用 HTTP 重定向循环的新型 SSRF 技术
预接管账号:结合 OTP 校验分离与空格绕过注册内部管理员邮箱
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:漏洞集萃 Pwn1 Pwn1《GraphQL 接口 Mutation别名导致的Hackerone DoS 漏洞》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论