GraphQL 是一种面向数据的 API 查询风格。传统的 API 拿到的是前后端约定好的数据格式,GraphQL 对 API 中的数据提供了一套易于理解的完整描述,客户端能够准确地获得它需要的数据,没有任何冗余,也让 API 更容易地随着时间推移而演进。
GraphQL API渗透测试指南
2023-09-05阅读:250
GraphQL 是一种面向数据的 API 查询风格。传统的 API 拿到的是前后端约定好的数据格式,GraphQL 对 API 中的数据提供了一套易于理解的完整描述,客户端能够准确地获得它需要的数据,没有任何冗余,也让 API 更容易地随着时间推移而演进。
GraphQL 是一种面向数据的 API 查询风格。传统的 API 拿到的是前后端约定好的数据格式,GraphQL 对 API 中的数据提供了一套易于理解的完整描述,客户端能够准确地获得它需要的数据,没有任何冗余,也让 API 更容易地随着时间推移而演进。
RESTful VS GraphQL
GraphQL API与Rest API最大的区别在于:GraphQL 通过将数据查询和数据修改分离开来,使得客户端能够更灵活地控制所需数据的粒度和类型,并且在多个资源之间建立关系。GraphQL只需一次请求就能够获取全部所需要的数据,而不是像RESTful API那样,要想获取所有数据就必须发起多次API请求。
前置知识
GraphQL查询方式
GraphQL是一种用于API的查询语言,首先我们就需要知道GraphQL有哪些查询方式。
主要有:
其中最为常见的是Query、Mutation、Subscription这三种,Query用于向服务端查询指定数据、Mutation用于在服务端修改或添加数据,具体可参考官方文档进行了解:https://graphql.org/learn/
GraphQL内省查询
简单来说就是,GraphQL内查机制,通常是内部可用,通过内省的方法获得相关信息,如对象定义、接口参数等信息。一般查询前面带有双下划线的就表示内省的一部分,比如:__Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive等,官方文档:https://graphql.org/learn/introspection/
GraphQL API发现
当我们在测试时,如何发现GraphQL API?下面介绍几种有效的方法。
常见的GraphQL路径判定
GraphQL API与Restful API不同,一般来说它的URL比较固定,这也是它的特性之一,从单个请求中获取应用程序所需的所有数据。
常见的GraphQL路径如下:/graphql/graphiql/v1/graphql/v2/graphql/v3/graphql/v1/graphiql/v2/graphiql/v3/graphiql/api/graphql/api/graphiql/graphql/api/graphql/console/console/playground/gql/query/graphql-devtools/graphql-explorer/graphql-playground/graphql.php/index.php?graphql......
通用查询探测
由于GraphQL API中存在一个__typename 的保留字段,该字段会以字符串形式返回查询对象的类型,所以我们可以向未知API发送query{__typename},如果响应中返回{"data": {"__typename": "query"}},那么就可以确定该API为GraphQL API。
内省查询
向未知API发送__schema字段使用自省来发现架构信息,该字段在所有查询的根类型上都可用。
query {__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}
可以查询到所有类型、字段、参数以及参数类型。
改变请求方法/报错信息判断
利用不同的请求方法(GET、POST)发起请求也能够进行GraphQL API的辨别,因为对于一些仅允许某种请求方法的GraphQL API而言,不同的请求方法返回的格式和内容也不同。
除此之外,根据报错信息可以判断是否为GraphQL API,主要特征是Syntax Error: Expected Name, found。
GraphQL API攻击面
内省查询攻击
通过了解GraphQL的内省查询机制,其实我们可以发现在相关系统没修改默认配置的情况下,我们可以通过__schema 或者 __type 等来进行系统级别的查询,以获取服务器上定义的所有类型、字段、敏感信息等。
通过内省查询,我们获取到系统所有相关字段及信息,如下图:
然后利用voyager工具将查询结果可视化。
获取数据结构以便进一步利用。
拒绝服务
GraphQL支持请求批处理,并且会对请求一个一个处理,这就导致可以利用批量查询来实施Dos攻击。
示例:
请求body:{"query":"query {\n systemUpdate\n}","variables":[]}, {"query": "query {\n systemUpdate\n}","variables":[]}, {"query":"query {\n systemUpdate\n}","variables":[]}
当查询类型相互引用时,通过构建一个循环查询,来实现Dos攻击。
query { Pastes { Owner { Pastes { Owner { Pastes { Owner { Pastes { Owner { Pastes { Owner { Pastes { Owner { name } } } } } } } } } } } } }
随着查询呈指数级增长,最终导致服务器崩溃。
由于GraphQL API不会对重读字段进行去重处理,所以还可以通过查询重复字段进行Dos攻击。
query { pastes { owner { pastes { ipAddr # 1 ipAddr # 2 ipAddr # 3 ipAddr # 4 ...... ipAddr # 1000 } } }}
越权查询/信息泄露
通过内审查询获取到相关信息后,可以进一步利用,GraphQL API作为单路由API接口在查询过程中往往会忽略一些鉴权问题,这可能导致越权漏洞的出现,并且泄露敏感信息。
例如在查询到存在id参数。
通过修改id参数进行水平越权,获取想要的敏感信息。
命令执行
由于GraphQL API没有充分验证输入或者没有严格过滤,导致在一些查询中可以通过链接的形式拼接 UNIX 命令,达到命令执行的目的。
或者是通过systemDiagnostics接受某些 UNIX 二进制文件作为调试目的的参数,例如 whoami、ps等,在获取相关凭证或者权限之后,可以进行拼接来达到命令执行的目的。
SQL注入
GraphQL API同样会可能存在SQL注入漏洞,可以对查询结构体中的一些参数进行SQL注入尝试。
这里对“test”参数进行SQL注入尝试。
加上单引号后返回报错信息。
后续直接利用sqlmap进行后续操作。
graphql注入
类似于SQL注入拼接字符串,在GraphQL API进行相关查询时,可以通过拼接的方式进行注入来获取数据或者改变查询逻辑。
正常查询:
mutation { create(content: "test", id: 1) { name password title }}
graphql注入:
mutation { editPaste(content: "test", id: 1) { name title } changePassword(password: "admin123") { name password title }}
XSS
GraphQL API同样也会遭受xss攻击,其实针对任何存在系统而言,如果没有相应的防御手段,没有对输入性参数进行过滤都可能遭受一些输入型漏洞攻击。
攻击载荷成功解析,此外也可以利用上传功能上传HTML脚本进行攻击测试。
SSRF
如果在GraphQL相关查询操作允许本地主机或其他服务器不限制输入,就可能遭受服务端请求伪造攻击
漏洞案例:
保护机制绕过
在GrapQL API中如果存在相关恶意输入保护机制,可以利用修改请求头参数进行绕过。
例如下面使用IDE时,进行命令执行时,存在保护机制。
发现Cookie中存在明显的disable字段。
修改disable为enable。
登陆爆破
在GraphQL API通过可以实现弱密码爆破来碰碰运气,不过还得分无登陆次数限制和有登陆次数限制两种情况。
如果无登陆次数的限制,直接可进行弱密码爆破。
如果一些网站存在登陆次数的限制,比如下面在爆破过程中。
GraphQL对象不能够包含多个同名的属性,所以我们可以利用别名来实现多个同属性的操作,这样如果系统只限制了API请求速率,那么也可以通过别名查询来实现登陆爆破。
JWT令牌伪造
可以通过相关工具获取GraphQL API的数据结构,这里我们就发现了存在新建用户的操作。
利用这个接口创建一个新用户。
成功查询到管理账号密码。
目录穿越/任意文件写入
在GraphQL API中相关文件上传/下载操作也可能存在目录穿越、任意文件读取、任意文件写入等漏洞。
例如通过目录穿越成功任意文件写入。
成功上传至tmp目录。
工具
除了传统的渗透测试工具以外,使用GraphQL API的工具也变得十分重要。
关于Portal Lab
星阑科技 Portal Lab 致力于前沿安全技术研究及能力工具化。主要研究方向为数据流动安全、API 安全、应用安全、攻防对抗等领域。实验室成员研究成果曾发表于BlackHat、HITB、BlueHat、KCon、XCon等国内外知名安全会议,并多次发布开源安全工具。未来,Portal Lab将继续以开放创新的态度积极投入各类安全技术研究,持续为安全社区及企业级客户提供高质量技术输出。
地址:北京市海淀区海淀大街38号银科大厦6层
Copyright © 2022 北京星阑科技有限公司. 京ICP备19053406号
提交成功