| Field | Detail |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | GraphQL API Vulnerabilities / Information Disclosure |
| Difficulty | Practitioner |
| Objective | Use introspection to discover that getUser exposes password fields, retrieve the administrator's credentials, and delete carlos |
Accidental Exposure of Private GraphQL Fields¶
Burp's HTTP history showed a GraphQL query from the blog page:
I sent the request to Repeater and replaced the query with Burp's introspection payload. The response revealed the full schema — scanning it found a getUser query with a password field in its selection set:
Saving the introspection result to the site map made browsing the schema faster — Burp's GraphQL integration parses the response and makes discovered queries clickable rather than requiring you to read raw JSON. getUser with its password field stands out immediately in the structured view.
query($id: Int!) {
getUser(id: $id) {
id
username
password
}
}
password exists directly on the User type and is returned by the getUser resolver — credentials should never be a returnable field on a general-purpose query. The developer added password to the type without considering that any API client could query getUser and request it. Introspection in production is what makes this a one-query discovery rather than a guessing exercise: without it, the field would require enumeration; with it, the full type map hands it over immediately.
Sending getUser with id: 1 — sequential IDs almost always start at 1 and the first account created is typically the bootstrap admin:
{
"data": {
"getUser": {
"id": 1,
"username": "administrator",
"password": "u5kruljcrhv7ivd6wv9g"
}
}
}
Administrator credentials in plaintext. Logged in, navigated to /admin, deleted carlos:
Lab solved