GraphQL安全问题
前言
实习的时候遇到graphql相关的安全测试,简单学习了一下,发现p神在18年就出相关议题总结了,在这里学习记录一下相关知识。
GraphQL简介
GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。
比较像是RESTful API的一个升级版
具体与REST和RPC的对比可以看这篇
RPC vs REST vs GraphQL
具体的详细介绍可以看https://graphql.cn/learn/
结构特性
GraphQL并没有绑定数据库,交互逻辑是客户端→GraphQL→后端代码→数据,不同于REST API的交互逻辑:客户端→后端代码→数据库。
GraphQL攻击面
内省开启导致的敏感信息泄漏
GraphQL内省是一个特殊查询,其支持的内省查询有两个__schema
、__type
。内省查询的作用是提供详细接口信息,简单的来说就是可以通过内省查询来获取GraphQL的接口文档,如对象定义、接口参数等信息。
例如查询注册的所有类
通过__type
查询制定对象的所有字段
生产环境开启内省会导致用户利用内省,即可列出 GraphQL中所有Query、Mutation、ObjectType、Field、Arguments。
防御方式:生产环境下关闭introspection即内省查询
GraphQL playground未授权访问
Playground是GraphQL一款开源的IDE,攻击者可在外网暴露的Playground上进行内省查询或者Query等常规操作,作用上类似插件:Altair GraphQL Client,都是为了方便调试GraphQL查询,本身自带内省查询获取接口文档
在访问的时候会自动发内省查询的包
使用以下请求内容可获取全部接口信息:
{"operationName":"IntrospectionQuery","variables":{},"query":"query IntrospectionQuery {\n __schema {\n queryType {\n name\n }\n mutationType {\n name\n }\n subscriptionType {\n name\n }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n}\n\nfragment 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\nfragment InputValue on __InputValue {\n name\n description\n type {\n ...TypeRef\n }\n defaultValue\n}\n\nfragment 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}\n"}
工具
- 浏览器插件:Altair GraphQL Client,填入合法GraphQL端点之后就可获取并查看接口文档,点击某条接口可在窗口中直接发起请求
- https://github.com/2fd/graphdoc 需要npm环境的工具,可生成本地的html文档
- https://ivangoncharov.github.io/graphql-voyager/ 在线的web端的分析平台,可直观展示接口与对象、参数的调用关系。将内省查询的json数据粘贴在内省框中,网页就会展示接口调用全貌
参考
https://www.leavesongs.com/content/files/slides/攻击GraphQL.pdf
https://www.anquanke.com/post/id/156930#h3-6
https://half90.top/2022/07/13/graphql-gong-ji-mian-zong-jie/
https://graphql.cn/learn/queries/
https://ithelp.ithome.com.tw/articles/10254196