GraphQL渗透测试详解
GraphQL介绍
GraphQL概述
GraphQL 是一种查询语言,用于 API 设计和数据交互。它是由 Facebook 发布的一款新型的数据查询和操作语言,自 2012 年起在内部使用,自 2015 年起获得开源许可。由于技术原因,越来越多的公司使用 GraphQL 并将其后端切换到这个新系统,但是,虽然这种查询语言有很多优点,但随着查询变得更加复杂,它也有一些安全问题。信息泄露、业务逻辑错误、IDOR 和不当访问控制是 GraphQL 端点上最常见的漏洞。
GraphQL与传统RESTful API的区别
GraphQL 允许客户端在一个请求中明确地指定需要的数据,并返回预期的结果,而不是像 RESTful API 那样只能获取预定义的资源。因此,GraphQL 简化了客户端与服务器之间的通信,提高了应用程序的性能和可扩展性。
与传统的 RESTful API 不同,GraphQL 通过将数据查询和数据修改分离开来,使得客户端能够更灵活地控制所需数据的粒度和类型,并且在多个资源之间建立关系。这样,客户端就可以很容易地实现高效的数据获取和更新,而无需为每个特定的用例编写特定的 API。
GraphQL应用
目前正在使用GraphQL的大型公司包括Facebook、PayPal、GitHub、Shopify、Twitter、Tesla、Hackerone等大型公司,可见GraphQL正在迅猛发展。
GraphQL渗透测试前置知识
GraphQL查询语言
我们根据前文已经得知,GraphQL是一种用于API的查询语言,它支持很多种查询方式:
- Query
- Mutation
- Subscription
- Input
- Enum
- Union
- Interface
我们接下来主要介绍一下Query、Mutation、Subscription这三种。
Query
Query是GraphQL中最常用的一种方式。它用于从服务端获取数据,类似于RESTful API的GET方法。使用Query可以指定需要返回的字段以及过滤条件。
例如,以下查询会请求服务器返回用户ID为1的用户名和电子邮件地址:
query {
user(id: 1) {
name
email
}
}
Mutation
Mutation用于在服务端修改或添加数据,类似于RESTful API的POST、PUT和DELETE方法。Mutation支持向服务端提交一些参数,并根据参数来执行相应的操作。
例如,以下Mutation会将用户ID为1的用户名更改为"NewName":
mutation {
updateUser(id: 1, name: "NewName") {
id
name
email
}
}
Subscription
Subscription是GraphQL中的一种高级特性,它允许客户端通过WebSocket连接实时接收来自服务器的数据更新。这对于需要实时通知的应用程序非常有用,如在线聊天、股票报价等。
例如,以下Subscription会订阅一个名为newMessage的频道,并在有新消息时返回消息内容:
subscription {
newMessage(channel: "chat") {
content
author
}
}
GraphQL渗透测试方法和流程
- 渗透测试准备工作
- 渗透测试步骤
- 枚举 GraphQL Schema
- 查询漏洞
- 注入漏洞
- 认证和授权漏洞
常见的GraphQL路径
/graphql
/graphql-console
/graphql-devtools
/graphql-explorer
/graphql-playground
/graphql-playground-html
/graphql.php
/graphql/console
/graphql/graphql
/graphql/graphql-playground
/graphql/schema.json
/graphql/schema.xml
/graphql/schema.yaml
/graphql/v1
/HyperGraphQL
/je/graphql
/laravel-graphql-playground
/lol/graphql
/portal-graphql
/v1/api/graphql
/v1/graphql
/v1/graphql-explorer
/v1/graphql.php
/v1/graphql/console
/v1/graphql/schema.json
/v1/graphql/schema.xml
/v1/graphql/schema.yaml
/v2/api/graphql
/v2/graphql
/v2/graphql-explorer
/v2/graphql.php
/graph
/graphql/console/
/graphiql
/graphiql.php
内省攻击
内省攻击本质上来说就是因为没有修改默认配置导致攻击者可以通过查询 __schema
或者 __type
等系统级别的 Schema 来获取服务器上定义的所有类型、字段、枚举等信息。攻击者可以利用这些信息去了解服务器的数据结构和业务逻辑,为下一步的攻击行动做准备。
内省攻击包含以下几个方面:
- 获取所有暴露的接口和类型信息:攻击者可以使用
__schema
查询来获取所有可用的 Schema 信息,包括对象类型、标量类型、枚举类型、接口类型和输入类型等。 - 获取所有字段信息:攻击者可以通过
__type.fields
查询来获取所有字段信息,包括字段名称、类型和描述等。 - 获取实际数据:攻击者可以通过查询实际数据,如用户账号、密码、秘密答案等,从而获取更高的权限或者直接篡改系统。
如下三段GraphQL 查询语句本质上是相同的,都是用于获取 GraphQL Schema 的元数据信息。它们的区别在于格式和编写方式
{__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}}}}}}}}
{"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}}}}}}}}"}
{"query":"query Query {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }"}
可以使用burp的插件进行分析
之后就可以查找其中一些漏洞了,比如修改ID参数查询其他人员信息
如果graphql内省模式被禁用,可以尝试使用工具。
https://github.com/nikitastupin/clairvoyance
https://github.com/assetnote/batchql
GraphQL 渗透测试实战案例分析
消耗服务器资源攻击案例
我们首先请求一次该接口发现用时30481
然后添加一个systemUpdate参数再次请求,可以看到时间变成了80725。如果添加更多的systemUpdate参数即可导致攻击发生。
SSRF漏洞案例
防御和修复 GraphQL 漏洞的建议
- 限制查询语句的深度和复杂度:GraphQL 支持嵌套查询和参数化查询,这使得攻击者可以构造非常复杂的查询来增加服务器的负载,甚至可能导致拒绝服务攻击。为了防范此类攻击,可以对查询语句进行深度和复杂度限制,以确保每个查询不会占用过多的资源。
- 限制查询的访问权限:GraphQL API 应该只允许授权访问,而不是任何人都可以访问。可以通过身份验证、IP 白名单、API 密钥等方式来限制查询的访问权限,从而避免恶意查询和攻击。
- 限制查询返回的字段和数据量:攻击者可以利用查询返回大量的数据来耗尽服务器资源或者获取敏感信息。为了防止这种情况发生,应该限制每个查询返回的字段和数据量,并对某些敏感字段进行隐藏或者过滤处理。
- 检查输入参数的合法性:GraphQL 允许客户端自由传递参数,这也使得攻击者可以利用参数注入漏洞来攻击系统。因此,在服务器端需要对输入参数进行严格校验和过滤,避免恶意参数的注入和攻击。
- 关闭内省查询:GraphQL 内省机制被用来获取服务器上定义的所有类型、字段、枚举等信息。攻击者可以利用这些信息了解服务器的数据结构和业务逻辑,从而进行进一步攻击。为了防范此类攻击,应该关闭或限制内省查询功能。
参考
https://blog.yeswehack.com/yeswerhackers/how-exploit-graphql-endpoint-bug-bounty/
https://zhuanlan.zhihu.com/p/390876937
注:技巧,可以了解 GraphQL 模式的功能。{"query":"query {\n system\n}","variables":null}
GraphQL渗透测试详解的更多相关文章
- 【HTB系列】靶机Frolic的渗透测试详解
出品|MS08067实验室(www.ms08067.com) 本文作者:大方子(Ms08067实验室核心成员) Hack The Box是一个CTF挑战靶机平台,在线渗透测试平台.它能帮助你提升渗透测 ...
- 【HTB系列】靶机Access的渗透测试详解
出品|MS08067实验室(www.ms08067.com) 本文作者:大方子(Ms08067实验室核心成员) Hack The Box是一个CTF挑战靶机平台,在线渗透测试平台.它能帮助你提升渗透测 ...
- 【HTB系列】靶机Teacher的渗透测试详解
出品|MS08067实验室(www.ms08067.com) 本文作者:大方子(Ms08067实验室核心成员) Kali: 10.10.14.50 靶机地址:10.10.10.153 先用nmap 对 ...
- 【HTB系列】靶机Vault的渗透测试详解
出品|MS08067实验室(www.ms08067.com) 本文作者:大方子(Ms08067实验室核心成员) Kali: 10.10.14.213 靶机地址:10.10.10.109 先用nmap探 ...
- 【HTB系列】靶机Chaos的渗透测试详解
出品|MS08067实验室(www.ms08067.com) 本文作者:大方子(Ms08067实验室核心成员) 知识点: 通过域名或者IP可能会得到网站的不同响应 Wpscan的扫描wordpress ...
- 【HTB系列】 靶机Swagshop的渗透测试详解
出品|MS08067实验室(www.ms08067.com) 本文作者:是大方子(Ms08067实验室核心成员) 总结与反思 使用vi提权 magento漏洞的利用 magescan 工具的使用 靶机 ...
- web 压力测试工具ab压力测试详解
Web性能压力测试工具之ApacheBench(ab)详解 原文:http://www.ha97.com/4617.html PS:网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压 ...
- redis压力测试详解
redis做压测可以用自带的redis-benchmark工具,使用简单,效果也比较不错. linux下一般无需下载,windows下redis-benchmark压力测试工具下载地址:http:// ...
- 大数据笔记(十九)——数据采集引擎Sqoop和Flume安装测试详解
一.Sqoop数据采集引擎 采集关系型数据库中的数据 用在离线计算的应用中 强调:批量 (1)数据交换引擎: RDBMS <---> Sqoop <---> HDFS.HBas ...
- Ubuntu14.04搭建JSP与Servlet开发环境及其测试详解
一,搭建JDK开发环境 1,在Java官网下载Jdk软件包,我的系统是64位Ubuntu14.04,所以选择jdk-8u25-linux-x64.tar.gz. 2,解压Jdk软件包 tar xvzf ...
随机推荐
- 吴恩达机器学习-终于完成ex4
几年前就想学习吴恩达的老课-机器学习,学了n次都没有坚持下来.其实很多东西都是这样,开始的时候信誓旦旦,信心满满,慢慢的就泄气了. 每天铺天盖地的深度学习,人工智能听得耳朵都要起茧子了.这算法,那框架 ...
- LoadRunner性能测试-app压力测试
步骤分为三步: 一,录制脚本 录制脚本原理:启动LR代理服务器监听设置好的端口号是否有请求发送给服务器,有请求时,代理服务器接收请求,并转发给对应的系统服务器,LR从而获取到请求的信息与数据,生成脚本 ...
- 使用hugo在gitee上写blog
1. 安装hugo 1)下载 Hugo Releases,选择hugo_xxx_Windows-64bit.zip(xxx位版本). 2)设置路径 我的电脑->属性->高级系统设置-> ...
- GoAccess - 可视化 Web 日志分析工具
Centos安装: yum -y install goaccess 使用goaccess命令生成HTML文件 LANG="en_US.UTF-8" bash -c 'goacces ...
- ubuntu系统使用 sudo: cd:找不到命令
1. https://blog.csdn.net/sazass/article/details/125694492 https://blog.csdn.net/weixin_34033624/arti ...
- 新搭建的禅道admin忘记密码
/opt/zbox/run/mysql/mysql -uroot -p 禅道数据库root默认密码123456 MariaDB [(none)]> show databases; +------ ...
- SQL语句用法总结
use quan56_goods; 使用数据库 show tables; 展示数据表 模糊查询 select * from tb_brand where name like '%林%'; 顺序 书写顺 ...
- layui使用OSS上传
1.首先要把aliyun-oss-sdk.js包下载下来,放到指定的目录下面 在要用的页面引入或者在index.html入口文件全局引入: <script src="util/ali ...
- Repeater 绑定数据如何根据数据列的内容排序
可指定Repeater的数据源 从数据库查询时直接排序,而后绑定数据这样
- BitBake使用攻略--BitBake的语法知识二
目录 写在前面 1. BitBake中的任务 2. 任务配置 2.1 依赖 2.1.1 内部任务间的依赖 2.1.2 不同菜谱下的任务间依赖 2.1.3 运行时态下的依赖 2.1.4 递归依赖 2.1 ...