> 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-1.md).

# lab-1

## Accessing Private GraphQL Posts

**Difficulty:** Apprentice

### Lab Description

The blog page for this lab contains a hidden blog post that has a secret password.

**Objective:** Find the hidden blog post and enter the password.

### Solution

**Step 1 — Enumerate visible posts**

Open the blog page and click through all visible posts while capturing traffic in Burp Suite. Reviewing the proxy history reveals four `POST /graphql/v1` requests, corresponding to post IDs `1`, `2`, `4`, and `5`. Post ID `3` is conspicuously absent from the browser — it's hidden but may still be queryable directly.

**Step 2 — Examine the GraphQL query structure**

Send one of the captured GraphQL requests to Repeater. The query structure looks like this:

```graphql
query getBlogPost($id: Int!) {
    getBlogPost(id: $id) {
        image
        title
        author
        date
        paragraphs
    }
}
```

With the variable:

```json
{"id": 2}
```

The query accepts a post ID and returns only the specific fields listed — `image`, `title`, `author`, `date`, and `paragraphs`.

**Step 3 — Query the hidden post**

Change the variable to `{"id": 3}` and send the request. A response comes back with content, but there's no password field — because the query only requests the fields listed above. There may be additional fields on this post that aren't being fetched.

**Step 4 — Use introspection to discover hidden fields**

To find what other fields the schema supports, run an introspection query. In Burp, go to **GraphQL > Set Introspection Query** and send it. The raw JSON response is hard to read directly, so:

1. Copy the full introspection JSON response.
2. Open [GraphQL Visualizer](https://graphql-visualizer.netlify.app/) (or a similar tool).
3. Select **Change Schema → Introspection** and paste the JSON.

The visual representation of the schema reveals two additional fields on the `getBlogPost` type that were never included in the original query: `isPrivate` and `postPassword`.

**Step 5 — Fetch the password**

Update the query to include the newly discovered fields:

```graphql
query getBlogPost($id: Int!) {
    getBlogPost(id: $id) {
        image
        title
        author
        date
        paragraphs
        isPrivate
        postPassword
    }
}
```

With the variable:

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

The response now includes the `postPassword` value and confirms `isPrivate: true`, explaining why the post was hidden in the browser UI.

Submit the password to complete the lab.

### Conclusion

The post was hidden at the UI layer only — the underlying GraphQL API had no field-level access control. Because GraphQL returns only the fields explicitly requested, the `postPassword` field was never exposed in normal use, but introspection revealed its existence and it could be queried freely once known.


---

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