New Job-Role Training Path: Active Directory Penetration Tester! Learn More

Attacking GraphQL

mini-module tag Mini-Module

GraphQL is a query language for APIs as an alternative to REST APIs. Clients are able to request data through GraphQL queries. If improperly configured or implemented, common web security vulnerabilities such as Information Disclosure, SQL Injection, and Insecure Direct Object Reference (IDOR) may arise.

4.81

Created by vautia

Medium Offensive

Summary

This module covers common misconfigurations and security vulnerabilities that arise in GraphQL APIs.

In more detail, this module covers the following:

  • Enumerating GraphQL APIs
  • Information Disclosure in GraphQL APIs
  • IDOR Vulnerabilities in GraphQL APIs
  • Injection Vulnerabilities in GraphQL APIs
  • DoS & Brute-Force Vulnerabilities in GraphQL APIs
  • Common Misconfigurations in GraphQL APIs

This module is broken into sections with accompanying hands-on exercises to practice each of the tactics and techniques we cover. The module ends with a practical hands-on skills assessment to gauge your understanding of the various topic areas.

You can start and stop the module at any time and pick up where you left off. There is no time limit or "grading", but you must complete all of the exercises and the skills assessment to receive the maximum number of cubes and have this module marked as complete in any paths you have chosen.

As you work through the module, you will see example commands and command output for the various topics introduced. It is worth reproducing as many of these examples as possible to reinforce further the concepts presented in each section. You can do this in the PwnBox provided in the interactive sections or your virtual machine.

A firm grasp of the following modules can be considered a prerequisite for the successful completion of this module:

  • Web Attacks
  • Cross-Site Scripting (XSS)
  • SQL Injection Fundamentals

Introduction to GraphQL


GraphQL is a query language typically used by web APIs as an alternative to REST. It enables the client to fetch required data through a simple syntax while providing a wide variety of features typically provided by query languages, such as SQL. Like REST APIs, GraphQL APIs can read, update, create, or delete data. However, GraphQL APIs are typically implemented on a single endpoint that handles all queries. As such, one of the main benefits of using GraphQL over traditional REST APIs is efficiency in using resources and requests.


Basic Overview

A GraphQL service typically runs on a single endpoint to receive queries. Most commonly, the endpoint is located at /graphql, /api/graphql, or something similar. For frontend web applications to use this GraphQL endpoint, it needs to be exposed. Just like REST APIs, we can, however, interact with the GraphQL endpoint directly without going through the frontend web application to identify security vulnerabilities.

From an abstract point of view, GraphQL queries select fields of objects. Each object is of a specific type defined by the backend. The query is structured according to GraphQL syntax, with the name of the query to run at the root. For instance, we can query the id, username, and role fields of all User objects by running the users query:

{
  users {
    id
    username
    role
  }
}

The resulting GraphQL response is structured in the same way and might look something like this:

{
  "data": {
    "users": [
      {
        "id": 1,
        "username": "htb-stdnt",
        "role": "user"
      },
      {
        "id": 2,
        "username": "admin",
        "role": "admin"
      }
    ]
  }
}

If a query supports arguments, we can add a supported argument to filter the query results. For instance, if the query users supports the username argument, we can query a specific user by supplying their username:

{
  users(username: "admin") {
    id
    username
    role
  }
}

We can add or remove fields from the query we are interested in. For instance, if we are not interested in the role field and instead want to obtain the user's password, we can adjust the query accordingly:

{
  users(username: "admin") {
    id
    username
    password
  }
}

Furthermore, GraphQL queries support sub-querying, which enables a query to obtain details from an object referencing another object. For instance, assume that a posts query returns a field author that holds a user object. We can then query the username and role of the author in our query like so:

{
  posts {
    title
    author {
      username
      role
    }
  }
}

The result contains the title of all posts as well as the queried data of the corresponding author:

{
  "data": {
    "posts": [
      {
        "title": "Hello World!",
        "author": {
          "username": "htb-stdnt",
          "role": "user"
        }
      },
      {
        "title": "Test",
        "author": {
          "username": "test",
          "role": "user"
        }
      }
    ]
  }
}

GraphQL queries support much more complex operations. However, this introductory overview is sufficient for this module. For more details, check out the Learn section on the official GraphQL website.

Sign Up / Log In to Unlock the Module

Please Sign Up or Log In to unlock the module and access the rest of the sections.