GraphQL安全问题

发布时间 2023-05-05 17:25:54作者: twosmi1e

前言

实习的时候遇到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