Challenge Solutions


Solutions

Overview


Legend

  • - GraphQL Official Documentation / Blog Posts
  • - Code Snippet
  • - GraphQL Security Utility
  • - Published Vulnerability (H1, CVE, etc.)

  There may be more than one way to exploit any given vulnerability, the solutions demonstrated below aim to illustrate one way of achieving successful exploitation.
  Some solutions include code snippets that are written in Python and use the requests library for HTTP requests.

Getting Started


The first essential step in every security test is to gain a bit of insight into the technology the remote server is using. By knowing the technologies in use, you can start building up a plan how to attack the application or the underlying infrastructure.

For GraphQL, a tool called graphw00f exists. Let's explore how it can help us achieve detection and fingerprinting of GraphQL.

Detecting GraphQL


Detecting where GraphQL lives is pretty trivial, there are common places where you would typically see a graphql endpoint. For example, /graphql, /v1/graphql, etc.

Point graphw00f at DVGA to figure out where GraphQL lives:

$>  python3 graphw00f.py -d -t http://localhost:5013/graphql
                +-------------------+
                |     graphw00f     |
                +-------------------+
                  ***            ***
                **                  ***
              **                       **
    +--------------+              +--------------+
    |    Node X    |              |    Node Y    |
    +--------------+              +--------------+
                  ***            ***
                     **        **
                       **    **
                    +------------+
                    |   Node Z   |
                    +------------+

                graphw00f - v1.0.3
          The fingerprinting tool for GraphQL
           Dolev Farhi (dolev@lethalbit.com)

Checking http://dvga.example.local:5013/graphql
[*] Found GraphQL at http://dvga.example.local:5013/graphql
[*] You can now try and fingerprint GraphQL using: graphw00f.py -t http://dvga.example.local:5013/graphql

Fingerprinting GraphQL


graphw00f can try and fingerprint GraphQL servers in order to determine the underlying implementation. By knowing what specific engine runs GraphQL, you can map what security mechanisms you may face during an assessment.

Point graphw00f at DVGA to figure out what technology it's running.

$> python3 graphw00f.py -t http://dvga.example.local:5013/graphql -f

[*] Checking if GraphQL is available at http://dvga.example.local:5013/graphql...
[*] Found GraphQL...
[*] Attempting to fingerprint...
[*] Discovered GraphQL Engine: (Graphene)
[!] Attack Surface Matrix: https://github.com/dolevf/graphw00f/blob/main/docs/graphene.md
[!] Technologies: Python
[!] Homepage: https://graphene-python.org
[*] Completed.
              

As you can see, DVGA runs graphene. Use the Attack Surface Matrix to see how Graphene ships GrapQL by default from a security perspective.


Denial of Service :: Batch Query Attack


Problem Statement

GraphQL supports Request Batching. Batched requests are processed one after the other by GraphQL, which makes it a good candidate for Denial of Service attacks, as well as other attacks such as Brute Force and Enumeration.

If a resource intensive GraphQL query is identified, an attacker may leverage batch processing to call the query and potentially overwhelm the service for a prolonged period of time.

The query systemUpdate seems to be taking a long time to complete, and can be used to overwhelm the server by batching a system update request query.

Resources
Exploitation Solution

Denial of Service :: Deep Recursion Query Attack


Problem Statement

In GraphQL, when types reference eachother, it is often possible to build a circular query that grows exponentially to a point it could bring the server down to its knees. Countermeasures such as max_depth can help mitigate these types of attacks.

The max_depth functionality acts as a safeguard, and defines how deep a query can get, ensuring deeply constructed queries will not be accepted by GraphQL.

The application offers two types, namely Owner and Paste, which reference eachother (an owner has a paste, and a paste has an owner), allowing a recursive query to be executed successfully.

Resources
Exploitation Solution

Denial of Service :: Resource Intensive Query Attack


Problem Statement

Sometimes, certain queries may be computationally more expensive than others. A query may include certain fields that would trigger more complex backend logic in order to fulfill the query resolution. As attackers, we can abuse it by calling these actions frequently in order to cause resource exhaustion.

In GraphQL, a concept called Query Cost Analysis exists, which assigns weight values to fields that are more expensive to resolve than others. Using this feature, we can then create an upper threshold to reject queries that are expensive. Alternatively, a cache feature can be implemented to avoid repeating the same request in a short time window.

Resources
Exploitation Solution

Denial of Service :: Field Duplication Attack


Problem Statement

Various GraphQL implementation do not bother de-duplicating repeating fields in GraphQL, allowing the user to multiply the same requested fields as they wish.

This causes extra load on the server to return the same fields over and over again.

There are a few ways in which this issue can be mitigated:

  • Field De-Duplication
  • Query Cost Analysis

Field De-Duplication can be achieved by using a middleware function to traverse the schema and remove any duplications, or simply analyze repeating patterns in order to reject the query.

Query Cost Analysis will be beneficial against these attacks, since each field will ultimately result in increased cost.

Resources
Exploitation Solution

Denial of Service :: Aliases based Attack


Problem Statement

In GraphQL, it is possible to run multiple queries without needing to batch them together.

If batching is disabled, you could build a query composed of multiple aliases calling the same query or mutation, if the server is not analyzing the cost of the query, it will be possible to overwhelm the server's resources by using expensive queries using aliases.

  • Query Middleware
  • Query Cost Analysis

Query Middleware is needed to identify the use of aliases in order to make a decision (reject/allow) based on your business logic.

Query Cost Analysis will be beneficial against these attacks, since each query will ultimately result in increased cost.

Resources
Exploitation Solution

Information Disclosure :: GraphQL Introspection


Problem Statement

GraphQL Introspection is a special query that uses the __schema field to interrogate GraphQL for its schema.

Introspection in itself is not a weakness, but a feature. However, if it is made available, it can be used and abused by attackers seeking information about your GraphQL implementation, such as what queries or mutations exist.

It is recommended to disable introspection in production to avoid data leakages.

Note: If introspection query is disabled, attackers may fall back to using the Field Suggestion feature to understand what queries and fields are supported by your GraphQL. Refer to Information Disclosure :: GraphQL Field Suggestionsattack for more information.

Resources
Exploitation Solution

Information Disclosure :: GraphQL Interface


Problem Statement

GraphQL has a an Integrated Development Environment named GraphiQL (note the i) that allows constructing queries in a friendly user interface.

GraphiQL is usually found in paths such as: /graphiql or /console, however, it can be in other places too.

Resources
Exploitation Solution

Information Disclosure :: GraphQL Field Suggestions


Problem Statement

GraphQL has a feature for field and operation suggestions. When a developer wants to integrate with a GraphQL API and types an incorrect field, as an example, GraphQL will attempt to suggest nearby fields that are similar.

Field suggestions is not a vulnerability in itself, but a feature that can be abused to gain more insight into GraphQL's schema, especially when Introspection is not allowed.

Resources
Exploitation Solution

Information Disclosure :: Server Side Request Forgery


Problem Statement

The GraphQL mutation importPaste accepts arbitrary host, port and scheme to import pastes from and does not restrict input such as localhost or other internal servers from being used. This may allow forging requests on behalf of the application server to target other network nodes.

Resources
Exploitation Solution

Code Execution :: OS Command Injection #1


Problem Statement

The mutation importPaste allows escaping from the parameters and introduce a UNIX command by chaining commands. The GraphQL resolver does not sufficiently validate the input, and passes it directly into cURL.

Resources
Exploitation Solution

Code Execution :: OS Command Injection #2


Problem Statement

The query systemDiagnostics accepts certain UNIX binaries as parameters for debugging purposes, such as whoami, ps, etc. It acts as a restricted shell. However, it is protected with a username and password. After obtaining the correct credentials, the restricted shell seems to be bypassable by chaining commands together.

Resources
Exploitation Solution

Injection :: Stored Cross Site Scripting


Problem Statement

The GraphQL mutations createPaste and importPaste allow creating and importing new pastes. The pastes may include any character without any restrictions. The pastes would then render in the Public and Private paste pages, which would result in a Cross Site Scripting vulnerability (XSS).

Resources
Exploitation Solution

Injection :: Log Injection // Log Spoofing


Problem Statement

GraphQL actions such as mutation and query have the ability to take an operation name as part of the query. Here is an example query that uses MyName as an operation name:

query MyName {
    getMyName
    {
      first
      last
    }
  } 

The application is keeping track of all queries and mutations users are executing on this system in order to display them in the audit log.

However, the application is not doing a fair job at verifying the operation name.

Resources
Exploitation Solution

Injection :: HTML Injection


Problem Statement

Similarly to the Cross Site Scripting problem, a paste can also include HTML tags that would render in the application, resulting in an HTML injection.

Resources
Exploitation Solution

Injection :: SQL Injection


Problem Statement

Pastes can be filtered using the filter parameter and it allows sending raw strings as query filters which are prone to SQL injections.

Resources
Exploitation Solution

Authorization Bypass :: GraphQL Interface Protection Bypass


Problem Statement

GraphiQL is available at the path /graphiql with a poorly implemented authorization check.

Resources
Exploitation Solution

Authorization Bypass :: GraphQL Query Deny List Bypass


Problem Statement

Creating an allow-list or deny-list for GraphQL is a common technique to prevent malicious queries from being resolved by GraphQL.

  • By defining an allow-list, the application server will have a "known good" queries it will allow, and reject anything else.
  • By defining a deny-list, the application server will have a "known bad" queries it will reject, and allow anything else.

In general, the allow-list approach is easier to maintain and less error-prone, since we only allow certain things we trust. It does not mean it cannot have flaws too.

The application has a deny-list mechanism implemented that attempts to reject Health queries using the systemHealth query.

The problem with this mechanism is that it does not take into consideration queries can have operation names.

Resources
Exploitation Solution

Miscellaneous :: Arbitrary File Write // Path Traversal


Problem Statement

The mutation uploadPaste allows uploading pastes from the user's computer by specifying the file along with the filename. The pastes are then stored on the server under a dedicated folder. The filename argument allows any string, effectively providing the ability to write the file to any location on the server's filesystem by traversing folders using ../../

Resources
Exploitation Solution

Miscellaneous :: GraphQL Query Weak Password Protection


Problem Statement

The query systemDiagnostics is an administrative functionality that allows running a subset of system commands on the server. The query is governed by a username and password before processing the command.

The password is weak, and the server has no rate limiting protections. This allows attackers to easily conduct brute force attacks against the server.

Resources
Exploitation Solution

Denial of Service :: Circular Fragment


Problem Statement

The GraphQL API allows creating circular fragments, such that two fragments are cross-referencing eachother. When a Spread Operator (...) references a fragment, which in return references a 2nd fragment that leads to the former fragment, may cause a recursive loop and crash the server.

Resources
Exploitation Solution

Information Disclosure :: Stack Trace Errors


Problem Statement

The dedicated GraphiQL API endpoint /graphiql throws stack traces and debugging messages upon erroneous queries.

Exploitation Solution

Authorization Bypass :: GraphQL JWT Token Forge


Problem Statement

Without logging in a user is able to forge the user identity claim within the JWT token for the me query operation.

Exploitation Solution