某不知名博客 某不知名博客
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carsaid

安全界的小学生
首页
  • 《vulcat文档》
  • Web安全

    • 《BurpSuite及官方实验室》
    • 《OSWE学习历程》
  • 云原生安全

    • 《Docker命令大全》
    • 《CKS考试学习指南》
    • 《旧-Kubernetes教程》
漏洞库
  • 《渗透工具大全》
  • 《云安全》
事件库
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前言

  • 服务器端主题(翻译)

  • 客户端主题(翻译)

  • 高级主题(翻译)

  • 扩展阅读(翻译)

  • 个人学习笔记

    • 说明
    • 笔记-服务端主题

    • 笔记-客户端主题

    • 笔记-高级主题

      • 不安全的反序列化笔记
      • GraphQL API漏洞笔记
        • GraphQL基本知识
          • 1、什么是GraphQL?
          • 2、什么是GraphQL模式?它定义了什么?
          • 3、GraphQL有哪几种数据处理操作?
          • 4、REST API和GraphQL的不同点?
        • GraphQL查询和变更
          • 1、什么是GraphQL查询?查询由哪几个关键部分组成?
          • 2、什么是GraphQL变更?变更由哪几个关键部分组成?
          • 3、查询和变更由哪几个组成部分?
        • GraphQL订阅和内省
          • 1、GraphQL订阅是什么?
          • 2、GraphQL内省是什么?
          • 3、GraphQL内省可能导致什么危害?
        • GraphQL API漏洞
          • 1、挖掘GraphQL API漏洞的流程是?
          • 2、如何查找GraphQL API端点?
          • 3、如何探测GraphQL API的模式信息?
          • 4、如何绕过GraphQL内省防御?
          • 5、如何使用别名绕过速率限制?
          • 6、GraphQL中的CSRF漏洞是如何产生?怎么利用?
        • GraphQL API漏洞防御
          • 1、防范常规的GraphQL攻击
          • 2、防范GraphQL暴力攻击/拒绝服务攻击
          • 3、防范GraphQL中的CSRF攻击
      • 服务端模板注入笔记
      • Web缓存投毒笔记
      • HTTP主机头攻击笔记
      • HTTP请求走私笔记
      • OAuth身份验证漏洞笔记
      • JWT攻击笔记
      • 原型链污染笔记
  • 实验室做题记录

  • BurpSuite及官方实验室
  • 个人学习笔记
  • 笔记-高级主题
carsaid
2023-11-07
目录

GraphQL API漏洞笔记

个人总结

参考:https://portswigger.net/web-security/graphql

- name: 个人总结
  desc: 参考:https://portswigger.net/web-security/graphql
  bgColor: '#F0DFB1'
  textColor: 'green'
1
2
3
4

# GraphQL API漏洞笔记

官方 GraphQL 学习教程 (opens new window)

官方 GraphQL 学习教程 (opens new window)

官方 GraphQL 学习教程 (opens new window)

# 1GraphQL基本知识

# 1、什么是GraphQL?

答案
  • GraphQL 是一种 API 查询语言,旨在促进客户端和服务器之间的高效通信。
  • 用户不需要知道数据的存储位置,他只需要指出想要的数据字段,然后将查询发送到 GraphQL 服务器,让服务器帮他获取数据并返回给他即可。
  • 在 REST API 中,GraphQL 有助于避免出现大型响应对象和重复调用。
  • GraphQL 与平台无关,因此它可以使用多种编程语言实现,并且可以与几乎任何数据存储进行通信。

GraphQL(API查询语言)的概念有点像 SQL(数据库查询语言),都是用于检索某种数据的查询语言。

-- 这是SQL
SELECT id, name, description FROM product WHERE id=1
1
2
# 这是GraphQL
query {
    product(id: 1) {
        id
        name
        description
    }
}
1
2
3
4
5
6
7
8

怎样,这俩是不是很像?

# 2、什么是GraphQL模式?它定义了什么?

答案

在 GraphQL 中,模式(schema)用于表示服务器前端和后端之间的协议。GraphQL 使用人类可读的语言来定义模式,并将可用的数据定义为一系列类型(各种数据类型)。然后,服务可以根据这些类型生成出具体的数据。

GraphQL 模式定义了服务数据的结构、可以列出可用的对象(类型)、字段和关系。

# 3、GraphQL有哪几种数据处理操作?

答案

三种:查询、变更和订阅

  • 查询并提取数据。
  • 变更可以被添加、更改或删除的数据。
  • 订阅类似于查询,但它设置了一个持久性连接,服务器通过该连接,可以将指定格式的数据 主动推送到客户端。

# 4、REST API和GraphQL的不同点?

答案

REST API

  • 多个端点,不同的端点用于区分不同的操作
  • 需要使用多种 HTTP 请求方法来进行不同的操作,例如一个/api/data端点,你通过GET请求访问之后是获取数据,但通过PUT请求访问就变成了上传数据
  • 响应的数据格式不固定,由服务器人员自定义

GraphQL

  • 单个端点,所有操作集成到一个端点上,GraphQL 会自动根据你发送的 类型/名称 来判断你具体要做哪一个操作
  • 通常使用POST请求来发送数据
  • 响应的数据格式一般为 JSON

# 2GraphQL查询和变更

# 1、什么是GraphQL查询?查询由哪几个关键部分组成?

答案

GraphQL 查询从数据存储中检索数据。它们大致等同于 REST API 中的 GET 请求。

查询由四个部分组成:

  • 操作类型。告诉服务器 当前请求需要进行哪些操作。
  • 查询名称。就是一个名称,有点像函数名,有助于调试。
  • 数据结构。你想要查询 并 让服务器返回的数据。
  • (可选)一个或多个参数。这些参数用于创建查询 并 返回特定对象的详细信息(例如,“为我提供 ID 为 123 的产品名称和描述”)。

这是一个示例查询:

  • 操作类型为query(查询),告诉服务器我要查询数据
  • 查询名称为myGetProductQuery,是自定义的名称,我取名叫 “abcdefg” 也可以,最好是一个方便记忆的名称
  • 数据结构为getProduct {name description},这里还包含一个参数id: 123,意思是获取getProduct对象中id为123的两个字段数据
    #Example query

    query myGetProductQuery {
        getProduct(id: 123) {
            name
            description
        }
    }
1
2
3
4
5
6
7
8

# 2、什么是GraphQL变更?变更由哪几个关键部分组成?

答案

GraphQL 变更以某种方式改变数据,包括添加、删除或编辑数据。它们大致等同于 REST API 的 POST、PUT 和 DELETE 方法。

变更的组成部分和 查询 一样,操作类型 + 操作名称 + 数据结构 + 可选参数。

这是一个示例变更请求:

  • 操作类型为mutation(变更),告诉服务器我要修改数据
  • 该请求省略了操作名称
  • 数据结构为createProduct {id name listed}
  • 提供了两个参数name: "Flamin' Cocktail Glasses", listed: "yes"
    #示例变更请求

    mutation {
        createProduct(name: "Flamin' Cocktail Glasses", listed: "yes") {
            id
            name
            listed
        }
    }

1
2
3
4
5
6
7
8
9
10

这是由以上请求产生的响应:

    #示例变更响应

    {
        "data": {
            "createProduct": {
                "id": 123,
                "name": "Flamin' Cocktail Glasses",
                "listed": "yes"
            }
        }
    }
1
2
3
4
5
6
7
8
9
10
11

# 3、查询和变更由哪几个组成部分?

点击查看

五个:字段、参数、变量、别名 和 片段。

以下是一个示例请求(字段 + 参数 + 别名):

  • 位于对象中的id、name.firstname和name.lastname是请求字段
  • 位于括号中的id: 1和id: 2是参数
  • product1和product2是别名,单个请求中不能出现同一个对象 “getProduct”,这会冲突,所以要设置别名
query myGetEmployeeQuery {
    product1: getProduct(id: 1) {
        id
        name {
            firstname
            lastname
        }
    }

    product2: getProduct(id: 2) {
        id
        name {
            firstname
            lastname
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

以下是第二个示例请求(字段 + 参数 + 变量 + 片段):

  • 位于Variables中的id是一个变量,它被定义为1
  • $id: ID!声明了一个变量,符号!表示该参数是必填字段,id: $id是一个使用了以上变量的动态参数
  • productInfo是一个片段,它包含Product中的多个字段。你可以通过...productInfo来使用它。
  • 片段是由多个字段组成的
query myGetEmployeeQuery($id: ID!) {
    getProduct(id: $id) {
        ...productInfo
        name {
            firstname
            lastname
        }
    }
}

Variables: {
    "id": 1
}

fragment productInfo on Product {
    id
    name
    listed
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3GraphQL订阅和内省

# 1、GraphQL订阅是什么?

答案

订阅是一种特殊类型的查询。它使客户端能够与服务器建立长期连接,这样服务器就可以向客户端推送实时更新,而不需要一直轮询数据。订阅主要用于对大型对象的微小更改,以及需要小型实时更新的功能(如聊天系统或协作编辑)。

  • 与常规查询和变更一样,订阅请求定义了要返回的数据结构。
  • 订阅通常使用 WebSocket 实现。

# 2、GraphQL内省是什么?

答案

(其实就是查询 GraphQL 自身的环境信息)

  • “内省” 是一个内置的 GraphQL 函数,可用于查询服务器以获取有关模式的信息。它通常被用于 GraphQL IDE 和文档生成工具等应用程序。
  • 与常规查询一样,你可以指定要返回的响应字段和结构。例如,你可能希望响应仅包含可用于变更的名称。

# 3、GraphQL内省可能导致什么危害?

答案

内省可能具有严重的信息泄露风险,因为它可用于访问潜在的敏感信息(例如字段描述)并帮助攻击者了解如何与 API 交互。

建议在生产环境中禁用 GraphQL 内省,这是最佳实践。

# 4GraphQL API漏洞

# 1、挖掘GraphQL API漏洞的流程是?

答案
  1. 查找 GraphQL API 端点
  2. 在发现的端点中寻找漏洞
    • 测试查询参数,如果 API 直接通过参数来访问对象,则可能存在 IDOR 漏洞
    • 测试别名,如果该端点存在速率限制,尝试使用别名绕过速率限制
    • 通过内省探测模式信息,尝试泄露潜在的敏感信息
  3. (如果有的话)绕过各种防御
    • 识别有缺陷的正则表达式,绕过 GraphQL 内省防御

# 2、如何查找GraphQL API端点?

答案

(GraphQL 服务通常会响应任何非 GraphQL 请求,并返回 “查询不存在” 等类似的错误。在测试 GraphQL 端点时,你应该牢记这一点)以下是一些查找和测试端点的方法:

  • 通用查询。将查询query{__typename}发送至任意 URL,如果响应中返回了{"data": {"__typename": "query"}},则此处可能是 GraphQL 端点
  • 通用端点名称。例如/graphql、/api、/api/graphql、/graphql/api、/graphql/graphql、/api/v1/graphql......等
  • 使用不同的 HTTP 方法和内容类型。GraphQL 端点一般只允许内容类型为application/json的POST请求,但某些端点可能会接受替代方法,例如内容类型为x-www-form-urlencoded的GET或POST请求
  • 初始检查。通过 BurpSuite 捕获请求,检查数据包中是否有任何 GraphQL 查询
  • 使用 Burp Scanner。通过 Burp Scanner 主动扫描目标站点,如果发现了任何 GraphQL 端点,则 BurpSuite 会报告 “GraphQL endpoint found” 问题

# 3、如何探测GraphQL API的模式信息?

答案

流程:

  • 使用和探测内省。使用以下查询{"query": "{__schema{queryType{name}}}"}来探测内省
  • 运行完整的内省查询。这部分内容太长了,要回去看文章
  • 可视化内省结果。可以使用在线工具 (opens new window)或 BurpSuite 扩展 InQL (opens new window) 来完成
  • 探测 “建议”。如果内省被禁用,则可以尝试通过 “建议” 来探测 API 模式信息。诸如 Clairvoyance (opens new window) 之类的工具可以完成自动化收集,以减轻工作量
  • 使用 Burp Scanner。通过 Burp Scanner 主动扫描目标站点,如果发现了任何可用的 “内省”,则 BurpSuite 会报告 “GraphQL introspection enabled” 问题。如果发现了任何可用的 “建议”,则 BurpSuite 会报告 “GraphQL suggestions enabled” 问题

# 4、如何绕过GraphQL内省防御?

答案
  • 添加混淆字符。在查询中添加空格、换行符、逗号等字符,GraphQL 会忽略这些字符,但有缺陷的正则表达式不会忽略它们
  • 篡改内容类型。尝试修改内容类型为x-www-form-urlencoded的 POST 请求
  • 使用其他 HTTP 请求方法。例如,尝试通过 GET 请求来发送查询:GET /graphql?query=query%7B__schema%0A%7BqueryType%7Bname%7D%7D%7D

# 5、如何使用别名绕过速率限制?

答案

别名的使用格式为<别名>:<对象名>(){...},你应该看得懂:

    #使用别名查询的请求
    query QueryUser($id: Int) {
        isUser(id:$id){
            valid
        }
        user2:isUser(id:$id){
            valid
        }
        user3:isUser(id:$id){
            valid
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13

# 6、GraphQL中的CSRF漏洞是如何产生?怎么利用?

答案

如果 GraphQL 没有实现任何 CSRF 令牌,且内容类型没有限定为application/json,则 GraphQL 可以被作为 CSRF 攻击的载体。

GraphQL+CSRF 漏洞利用的构造方式,与常规的 CSRF 攻击一样(都是通过 GET/POST 请求发送数据,当然一样了)。

# 5GraphQL API漏洞防御

# 1、防范常规的GraphQL攻击

答案
  • 对于内部 GraphQL API 服务,应该禁用内省,降低不必要的信息泄露风险。
  • 如果 GraphQL API 服务提供给公众使用,你可能需要启用内省,此时应该检查 API 模式信息,以确保它不会向大众公开非预期的字段。
  • 确保你的 API 模式信息,不会公开任何私有用户字段,例如电子邮件地址或用户 ID。
  • 确保 “建议” 已被禁用。防止攻击者使用 Clairvoyance 或类似的工具来收集有关底层模式的信息。解决方案请参阅此 GitHub 项目 (opens new window)。

(你可能会疑惑,为什么内部要禁用,外部却启用内省?)

  • 因为内部使用的 GraphQL 可能存有敏感信息,所以要禁用内省,以防止内部敏感信息被泄露
  • 外部使用的 GraphQL 都是开放的公共接口,保存的一般都是公开信息,开放内省是为了让用户了解 API 结构,以更好地与接口进行数据交互

# 2、防范GraphQL暴力攻击/拒绝服务攻击

针对两个漏洞进行防御:

  • 通过别名绕过速率限制
  • 通过 GraphQL 实现的 DoS 攻击
答案
  • 限制 API 查询的深度(查询的嵌套层级数)。大量的查询可能会对性能造成影响,产生 DoS 攻击。
  • 限制 API 所能接收 字段/别名 的最大数量。例如,攻击者发送一千个带有别名的字段,进行暴力攻击。
  • 限制查询的最大字节数。
  • 实现成本分析。识别一个 查询任务 所需要消耗的资源成本,如果查询过于复杂而无法运行,则丢弃该查询任务。

# 3、防范GraphQL中的CSRF攻击

答案
  • 只接受内容类型为 JSON 数据的 POST 请求
  • 验证内容类型 与 实际接收的数据是否吻合
  • 在 GraphQL 中实现 CSRF 令牌机制
编辑 (opens new window)
不安全的反序列化笔记
服务端模板注入笔记

← 不安全的反序列化笔记 服务端模板注入笔记→

最近更新
01
API测试笔记
04-30
02
msfvenom
03-29
03
Metasploit
03-29
更多文章>
Theme by Vdoing | Copyright © 2023-2024 Carsaid | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式