Bp靶场portswigger-GraphQLAPI

admin 2025年3月6日17:00:13评论11 views字数 6840阅读22分48秒阅读模式

关注该公众号,不定时分享各种资源和文章,感谢关注:)

查找 GraphQL 端点

在测试 GraphQL API 之前,您首先需要找到其端点。由于 GraphQL API 对所有请求都使用相同的端点,因此这是一条很有价值的信息。

笔记

本节介绍如何手动探测 GraphQL 端点。但是,Burp Scanner 可以在扫描过程中自动测试 GraphQL 端点。如果发现任何此类端点,它会引发“找到 GraphQL 端点”问题。

  • 单一端点
  • 强类型系统
  • 实时数据:支持订阅(Subscriptions),允许客户端订阅特定事件并在数据变化时接收实时更新
  • 查询语言
  • 高效性

通用查询

如果您发送query{__typename}到任何 GraphQL 端点,它将{"data": {"__typename": "query"}}在其响应中的某个位置包含该字符串。这称为通用查询,是探测 URL 是否对应于 GraphQL 服务的有用工具。

查询有效,因为每个 GraphQL 端点都有一个保留字段,__typename该字段以字符串形式返回查询对象的类型。

通用端点名称

  • /graphql
  • /api
  • /api/graphql
  • /graphql/api
  • /graphql/graphql

如果这些常见端点没有返回 GraphQL 响应,您也可以尝试附加/v1到路径。

笔记

GraphQL 服务通常会对任何非 GraphQL 请求做出“查询不存在”或类似错误的响应。在测试 GraphQL 端点时,您应该牢记这一点。

请求方法

尝试查找 GraphQL 端点的下一步是使用不同的请求方法进行测试。

生产 GraphQL 端点的最佳做法是仅接受内容类型为 的 POST 请求application/json,因为这有助于防范 CSRF 漏洞。但是,某些端点可能会接受替代方法,例如使用x-www-form-urlencoded内容类型的 GET 请求或 POST 请求。

如果您无法通过向通用端点发送 POST 请求来找到 GraphQL 端点,请尝试使用其他 HTTP 方法重新发送通用查询。

一般是application/json的POST请求 -> 通用查询

x-www-form-urlencoded的Get或Post请求

初步检查

发现端点后,您可以发送一些测试请求,以进一步了解其工作原理。如果端点正在为网站提供支持,请尝试在 Burp 的浏览器中探索 Web 界面,并使用 HTTP 历史记录检查发送的查询。

利用未净化的参数

此时,您可以开始寻找漏洞。测试查询参数是一个很好的起点。

如果 API 使用参数直接访问对象,则可能容易受到访问控制漏洞的影响。用户只需提供与该信息相对应的参数,就可能访问他们不应该拥有的信息。这有时被称为不安全的直接对象引用 (IDOR)。

更多信息

  • 有关 GraphQL 参数的一般解释,请参阅参数。
  • 有关 IDOR 的更多信息,请参阅不安全的直接对象引用 (IDOR)。

例如,以下查询请求在线商店的产品列表:

     #Example product query

query {
products {
id
name
listed
}
}

返回的产品列表仅包含列出的产品。

     #Example product response
{
"data": {
"products": [
{
"id": 1,
"name": "Product 1",
"listed": true
},
{
"id": 2,
"name": "Product 2",
"listed": true
},
{
"id": 4,
"name": "Product 4",
"listed": true
}
]
}
}

根据这些信息,我们可以推断出以下内容:

  • 产品被分配一个连续的ID。
  • 产品 ID 3 在列表中缺失,可能是因为它已被除名。

通过查询缺失产品的 ID,我们可以获得其详细信息,即使该产品未在商店中列出且未由原始产品查询返回。

#Query to get missing product

query {
product(id: 3) {
id
name
listed
}
}

    #Missing product response

{
"data": {
"product": {
"id": 3,
"name": "Product 3",
"listed": no
}
}
}

发现架构信息

测试 API 的下一步是将有关底层模式的信息拼凑在一起。

最好的方法是使用自省查询。自省是一个内置的 GraphQL 函数,可让您查询服务器以获取有关架构的信息。

自省可帮助您了解如何与 GraphQL API 交互。它还可能泄露潜在的敏感数据,例如描述字段。

使用自省

要使用自省来发现架构信息,请查询该__schema字段。此字段在所有查询的根类型上可用。

与常规查询一样,您可以指定运行自省查询时要返回的响应的字段和结构。例如,您可能希望响应仅包含可用突变的名称。

笔记

Burp 可以为您生成自省查询。有关更多信息,请参阅使用自省访问 GraphQL API 模式。

探索自省

在生产环境中禁用自省是最佳做法,但并不总是遵循此建议。

您可以使用以下简单查询来探测自检。如果启用了自检,响应将返回所有可用查询的名称。

#Introspection probe request
{
"query": "{__schema{queryType{name}}}"
}

笔记

Burp Scanner 可以在扫描过程中自动测试自省。如果发现自省已启用,则会报告“GraphQL 自省已启用”问题。

运行完整的自省查询

下一步是对端点运行完整的自省查询,以便您可以获得有关底层模式的尽可能多的信息。

下面的示例查询返回所有查询、变异、订阅、类型和片段的完整详细信息。

     #Full introspection query

query IntrospectionQuery {
__schema { # 这是GraphQL内省的根入口,用于访问整个Schema的元数据
queryType { # 返回根操作类型的名称
name
}
mutationType { # 返回根操作类型的名称
name
}
subscriptionType { # 返回根操作类型的名称
name
}
types { # 返回Schema中所有类型的列表, 并通过FullType片段获取整个类型的详细信息
...FullType
}
directives { # 返回Schema支持的指令(如@include, #deprecated)
name
description
args {
...InputValue
}
onOperation #Often needs to be deleted to run query
onFragment #Often needs to be deleted to run query
onField #Often needs to be deleted to run query
}
}
}

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
}
}
}
}

笔记

如果启用了自省但上述查询未运行,请尝试从查询结构中删除onOperationonFragmentonField指令。许多端点不接受这些指令作为自省查询的一部分,通过删除它们,您通常可以更成功地进行自省。

可视化自省结果

对内省查询的响应可能包含大量信息,但通常很长且难以处理。

您可以使用 GraphQL 可视化工具更轻松地查看架构实体之间的关系。这是一个在线工具,它获取自检查询的结果并生成返回数据的可视化表示,包括操作和类型之间的关系。

建议

即使内省功能完全被禁用,有时您也可以使用建议来收集有关 API 结构的信息。

建议是 Apollo GraphQL 平台的一项功能,服务器可以在错误消息中建议查询修改。这些通常用于查询略有错误但仍可识别的情况(例如There is no entry for 'productInfo'. Did you mean 'productInformation' instead?)。

您可以从中收集到有用的信息,因为响应实际上泄露了模式的有效部分。

Clairvoyance 是一款使用建议自动恢复全部或部分 GraphQL 架构的工具,即使在禁用自省的情况下也是如此。这大大减少了从建议响应中拼凑信息所花费的时间。

您无法直接在 Apollo 中禁用建议。请参阅此 GitHub 线程以了解解决方法。

笔记

Burp Scanner 可以在扫描过程中自动测试建议。如果发现有效建议,Burp Scanner 会报告“GraphQL 建议已启用”问题。

1、实验室:访问私人 GraphQL 帖子

抓包,可以抓到api接口,修改id值,对应的是不同的文章

Bp靶场portswigger-GraphQLAPI
api-07
测试发现,ID为3的文章 没有存在在浏览器中 -> 说明是隐藏的文章

BP自带的内省查询进行测试,发现postPassword字段

Bp靶场portswigger-GraphQLAPI
api-08

回到原先的查询字段,添加上postPassword

Bp靶场portswigger-GraphQLAPI
api-09

2、实验室:意外暴露私有 GraphQL 字段

抓登录的包,发现api接口,自省测试

Bp靶场portswigger-GraphQLAPI
api-10

测试响应完,右键发送到site map,查看

Bp靶场portswigger-GraphQLAPI
api-11

发现一个api查询,是针对id查询,返回对应的用户名和密码

Bp靶场portswigger-GraphQLAPI
api-12

绕过 GraphQL 自省防御

如果您无法针对正在测试的 API 运行内省查询,请尝试在__schema关键字后插入特殊字符。

当开发人员禁用自省时,他们可以使用正则表达式来排除__schema查询中的关键字。您应该尝试空格、换行符和逗号等字符,因为 GraphQL 会忽略它们,但有缺陷的正则表达式不会。

因此,如果开发人员仅排除了__schema{,那么下面的自省查询将不会被排除。

     #Introspection query with newline

{
"query": "query{__schema
{queryType{name}}}"
}

如果此方法无效,请尝试通过其他请求方法运行探测,因为自省只能通过 POST 禁用。请尝试 GET 请求,或内容类型为x-www-form-urlencodedPOST 请求。

下面的示例展示了通过 GET 发送的内省探测,带有 URL 编码的参数。

 
# Introspection probe as GET request

GET /graphql?query=query%7B__schema%0A%7BqueryType%7Bname%7D%7D%7D

笔记

您可以将 GraphQL 查询保存到站点地图。有关更多信息,请参阅使用 GraphQL

3、实验室:寻找隐藏的 GraphQL 端点

直接抓包找不到api的数据包,测试/api -> 返回的是查询请求"Query not present" -> 说明存在这个接口,只是参数不合规

Bp靶场portswigger-GraphQLAPI
api-13
直接set自省查询是不行的,有过滤
在schema后面跟一个换行%0a 可以绕过
右键发送到site map
Bp靶场portswigger-GraphQLAPI
api-14
根据右边的接口进行查询 carlos用户的id
用左边的接口进行删除

使用别名绕过速率限制

通常,GraphQL 对象不能包含多个同名的属性。通过显式命名您希望 API 返回的属性,别名可让您绕过此限制。您可以使用别名在一个请求中返回同一类型对象的多个实例。

更多信息

有关 GraphQL 别名的更多信息,请参阅别名。

虽然别名旨在限制您需要进行的 API 调用的数量,但它们也可用于强制执行 GraphQL 端点。

许多端点都会==设置某种速率限制器来防止暴力攻击==。一些速率限制器==基于==收到的 HTTP ==请求数==而不是在端点上执行的操作数来工作。由于别名实际上允许您在单个 HTTP 消息中发送多个查询,因此它们可以绕过此限制。

下面的简化示例显示了一系列别名查询,用于检查商店折扣代码是否有效。此操作可能会绕过速率限制,因为它是单个 HTTP 请求,尽管它可能用于同时检查大量折扣代码。

 
#Request with aliased queries

query isValidDiscount($code: Int) {
isvalidDiscount(code:$code){
valid
}
isValidDiscount2:isValidDiscount(code:$code){
valid
}
isValidDiscount3:isValidDiscount(code:$code){
valid
}
}

4、实验室:绕过 GraphQL 暴力破解保护

抓登录的数据包,有api接口,根据题目要求,先进行测试

Bp靶场portswigger-GraphQLAPI
api-15
我已知wiener的账号密码
再加一组错误的密码,进行测试,看是否多组数据能够成功登录
测试成功

根据提示,在控制台运行js脚本,然后多组测试carlos

Bp靶场portswigger-GraphQLAPI
api-16

得到正确的token,抓包修改token就可以成功以carlos身份登录

GraphQL CSRF

跨站点请求伪造 (CSRF) 漏洞使攻击者能够诱导用户执行他们不想执行的操作。这是通过创建一个恶意网站来伪造对易受攻击的应用程序的跨域请求来实现的。

GraphQL 可用作 CSRF 攻击的载体,攻击者可以创建漏洞,导致受害者的浏览器以受害者用户的名义发送恶意查询。

GraphQL 上的 CSRF 漏洞是如何产生的?

GraphQL 端点未验证发送给它的请求的内容类型且未实现 CSRF 令牌时,可能会出现 CSRF 漏洞。

只要内容类型经过验证,使用内容类型的 POST 请求application/json就不会被伪造。在这种情况下,即使受害者访问了恶意网站,攻击者也无法让受害者的浏览器发送此请求。

但是,浏览器可以发送诸如 GET 之类的替代方法或任何内容类型为x-www-form-urlencoded的请求,因此如果端点接受这些请求,用户可能会容易受到攻击。在这种情况下,攻击者可能能够利用漏洞向 API 发送恶意请求。

对于基于 GraphQL 的 CSRF 漏洞,构建 CSRF 攻击和提供漏洞利用的步骤与“常规”CSRF 漏洞相同。有关此过程的更多信息,请参阅如何构建 CSRF 攻击。

5、实验室:通过 GraphQL 执行 CSRF 攻击

防止 GraphQL 攻击

为了防止许多常见的 GraphQL 攻击,在将 API 部署到生产环境时请执行以下步骤:

  • 如果您的 API 不打算供公众使用,请禁用其自省功能。这会使攻击者更难获取有关 API工作原理的信息,并降低不必要的信息泄露风险。

    有关如何在 Apollo GraphQL 平台中禁用自省的信息,请参阅此博客文章。

  • 如果您的 API 旨在供公众使用,那么您可能需要启用自省功能。但是,您应该检查 API 的架构,以确保它不会向公众公开非预期字段。

  • 确保建议已禁用。这可防止攻击者使用 Clairvoyance 或类似工具来收集有关底层架构的信息。

    您无法直接在 Apollo 中禁用建议。请参阅此 GitHub 线程以了解解决方法。

  • 确保您的 API 模式不会暴露任何私人用户字段,例如电子邮件地址或用户 ID

防止 GraphQL 暴力攻击

使用 GraphQL API 时,有时可以绕过标准速率限制。有关此示例,请参阅使用别名绕过速率限制部分。

考虑到这一点,您可以采取一些设计步骤来保护您的 API 免受暴力攻击。这通常涉及限制 API 接受的查询的复杂性,并减少攻击者执行拒绝服务 (DoS) 攻击的机会。

防御暴力攻击:

  • 限制 API 查询的查询深度。术语“查询深度”是指查询中的嵌套层数。嵌套过多的查询可能会对性能产生重大影响,并且如果被接受,可能会为 DoS 攻击提供机会。通过限制 API 接受的查询深度,您可以降低发生这种情况的可能性。
  • 配置操作限制。操作限制使您能够配置 API 可以接受的唯一字段、别名和根字段的最大数量。
  • 配置查询可以包含的最大字节数。
  • 考虑在您的 API 上实施成本分析。成本分析是一个过程,通过该过程,图书馆应用程序在收到查询时识别与运行查询相关的资源成本。如果查询的计算复杂度过高而无法运行,API 会将其丢弃。

通过 GraphQL 预防 CSRF

为了特别防御 GraphQL CSRF 漏洞,在设计 API 时请确保以下几点:

  • 您的 API 仅接受通过 JSON 编码的 POST 进行的查询。
  • API 验证提供的内容是否与提供的内容类型相匹配。
  • 该API具有安全的CSRF令牌机制。

工具

可视化工具:http://nathanrandal.com/graphql-visualizer/

原文始发于微信公众号(夜风Sec):Bp靶场portswigger-GraphQLAPI

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月6日17:00:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Bp靶场portswigger-GraphQLAPIhttps://cn-sec.com/archives/3803414.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息