GraphQL浅记
在2022New Star碰到GraphQL相关题目(ezAPI),记录一下GraphQL的学习。
GraphQL简介
GraphQL是由Facebook开发并于2015年公开发布的数据查询语言。是REST API的替代品。作为一种 API 查询语言,GraphQL 不要求实现它的应用服务器使用特定的编程语言或存储系统,且它与底层数据库无关,可以与MySQL数据库一起使用,也可以与Nosql数据库搭配。
与其类似的还有RESTful API,区别在于,RESTful API需要多个API实现不同的功能,而GraphQL获取多个资源,只用一个请求。但是也不是所有需求都适用GraphQL,简单的需求还是使用RESTful API,GraphQL查询的数据是图状数据结构,一些没有图的概念的数据使用GraphQL并没有显著的效果。
SQL是结构化查询语言,GraphQL是图表化查询语言。
GraphQL查询响应格式
基本的GraphQL查询
1 |
|
基本的GraphQL响应
响应结果则是json类型:
1 |
|
官方文档:
1 |
|
例如这样的
类似于json,但是有很多换行符。
GraphQL主要操作
字段
GraphQL 关于请求对象上的特定字段,即要操作(查询更改…)的对象。
参数
GraphQL 对象类型上的每一个字段都可能有零个或者多个参数。
GraphQL基本参数类型
- String, Int, Float, Boolean和ID。在schema声明时直接使用。 (ID不能重复使用)
- !(叹号)代表参数不能为空。
基础操作
类似于SQL的增删改查,GraphQL主要有三种操作query、mutation 和 subscription,分别对应查询、变更和订阅。
官方文档:
1 |
|
内省查询
GraphQL内置了内省系统,通过它给出的内省方法,我们可以获得对象名称、类型、参数等多种信息。
官方文档:
1 |
|
我的理解:information_schema(像不像 (*^▽^*)
重点
上述查询是可交互的。也就是你可以按你喜欢来改变查询,然后看看新的结果。(也就是可以更改查询语句得到想要的结果)
GraphQL 对象类型上的每一个字段都可能有零个或者多个参数。(参数个数不同可能得不到我们想要的内容,比如flag)
例子
1 |
|
1 |
|
从users_user_by_pk这个接口查询id=1的字段的name属性。
GraphQL 端点
常见的GraphQL端点:
1 |
|
可以通过向端点发送一个无效查询,是否报错判断端点。
在测试应用程序时,验证是否可以在没有一般授权令牌标头的情况下发出请求,因为GraphQL本身没有提供任何数据保护手段,只能通过其他方法进行访问控制,不让端点被恶意利用。
GraphQL可能存在的隐患
未授权访问
开发者在使用时经常会忽略接口的鉴权问题。导致访问控制容易被破坏,不安全的对象直接引用甚至SQL或NoSQL进行注入。有时候客户端调用查询接口,直接传入了id等信息并未做好权限校验,就有可能存在水平越权。
GraphQL内省查询
最常见的问题,内省查询本来应该是仅允许内部访问,但配置错误导致任何攻击者可以利用内省查询。
payload:
1 |
|
返回包返回的就是该API端点的所有信息。
通过内省查询得到很多接口信息,造成信息泄露。
嵌套查询DoS
当业务的变量互相关联,如以下graphql定义为这样时,就可能无限展开,造成拒绝服务。
它们可以允许恶意客户端通过过度复杂的查询来执行DoS(拒绝服务)攻击,占用服务器的资源。
1 |
|
针对DoS的简单修复方式可以是设置超时,最大深度或查询复杂度阈值。
SQL注入
graphql的sql注入与一般的sql注入类似,都是可以通过构造恶意语句达到注入获取数据或改变查询逻辑的目的。p神在先知大会上讲过该类问题,借用p神的2张PPT。
例题
参考2022NewStarCTF ezAPI。
参考文章
https://blog.doyensec.com/2018/05/17/graphql-security-overview.html
https://www.anquanke.com/post/id/147455#h2-9
https://www.secpulse.com/archives/148242.html
https://zhuanlan.zhihu.com/p/124019191#
https://www.zhihu.com/question/264629587
https://zhuanlan.zhihu.com/p/506391425
https://blog.csdn.net/A_bad_horse/article/details/105377150
官方文档: