I found a direct line into the backend of a Fortune 500 company's private code infrastructure. No passwords, no tokens — just one forgotten endpoint. Here is the anatomy of a GraphQL exposure.
Introduction: The Fallacy of the Front Door
In the world of modern enterprise security, the "Front Door" is usually impenetrable. Large corporations protect their internal tools — like source code repositories, CI/CD pipelines, and project boards — behind heavy layers of Single Sign-On (SSO) and Multi-Factor Authentication (MFA).
When you visit git.company.com, you expect to be immediately redirected to an Okta or Microsoft login page. If you aren't an employee, you shouldn't see anything.
But what if I told you that while the front door was locked, the developer left a side window wide open?
This is the story of how I bypassed the SSO mechanism of a major automotive company's private GitLab instance, accessing sensitive internal architecture data, AI configurations, and security audit definitions — all because of a default feature called the GraphQL Explorer.
Phase 1: The Discovery
I was performing reconnaissance on a scope that included cloud-hosted development tools (*.redacted-cloud.com). My target was a private GitLab instance used by their internal developers.
When I visited the main URL, I was blocked immediately:
Redirecting to SSO…
I couldn't brute force it. I couldn't phish it. The authentication was solid.
However, modern applications, especially those built on GitLab, rely heavily on GraphQL. Unlike REST APIs, which have many endpoints (/api/v1/users, /api/v1/projects), GraphQL usually has one endpoint (/api/graphql) that handles everything.
To help developers test these queries, many applications include a GUI tool called GraphiQL (or GraphQL Explorer).
I tried a common fuzzing technique — appending known developer tools to the URL. https://git.redacted-cloud.com/-/graphql-explorer
The Result: Instead of an SSO redirect, I was greeted with the GraphQL IDE interface.
- Status: 200 OK
- Auth Required: None.
I was now sitting inside an unauthenticated console with a direct line to the backend API.
Phase 2: The "Introspection" Nightmare
Accessing the Explorer is bad, but it's only fatal if Introspection is enabled.
What is Introspection? It is a feature that allows you to ask the API: "Tell me everything you can do." It returns the entire schema — every data type, every query, every mutation, and every field name available in the database.
I clicked the "Docs" tab in the Explorer. It loaded. The entire API schema was visible.
This is where the "Information Disclosure" transforms into a "Hacker's Blueprint." I didn't need to guess endpoints; the server handed me a map of its internal logic.
Phase 3: Mining the Gold (The Exploits)
Now that I had the map, it was time to see what I could steal. I started crafting queries to see what the server would execute without a session token.
1. The Blueprint of Security: auditEventDefinitions
My first hit was massive. I found a query object called auditEventDefinitions. This is used to define what actions the system logs for security auditing.
The Query:
{
auditEventDefinitions {
nodes {
name
description
featureCategory
introducedByIssue
introducedByMr
milestone
}
}
}The Leak: The server returned a massive JSON list of every internal security event.
- Why this matters: It leaked links to internal development tickets (
introducedByIssue) and Merge Requests (introducedByMr). It revealed exactly which compliance features (compliance_management) were active. - The Risk: An attacker can use this to map the exact version of the software and identify which security patches might be missing based on the "Milestone" data.
2. Leaking AI Secrets: aiChatContextPresets
We live in the age of AI, and this company was no exception. I found queries related to their internal AI coding assistants.
The Query:
{
aiChatContextPresets {
questions
}
}The Leak: This returned the preset prompts and context configurations used by their internal AI tools. While not user data, this exposes proprietary configuration and gives insight into how their internal "Copilots" are wired.
3. Tech Stack Enumeration: topics
I wanted to know what technologies they were building. I queried the topics node.
The Query:
{
topics(first: 20) {
nodes {
id
name
}
}
}The Leak: The server listed internal tags used for their projects:
opentelemetryterraformandroidspring-bootcicd-components
The Risk: This is pure gold for a targeted attack. I now know they use Terraform and Spring Boot. I stop looking for PHP vulnerabilities and start looking for Java Deserialization or Terraform state leaks.
Phase 4: The Report
I compiled a detailed report.
- Vulnerability: Broken Access Control / Information Disclosure.
- Severity: High (P2).
- Impact: Unauthenticated mapping of internal infrastructure, leakage of development pipelines, and exposure of AI configurations.
I explained that while I couldn't delete projects (those mutations required Auth), the ability to map the entire backend bypassed the fundamental promise of their SSO protection.
Phase 5: The "Not Applicable" Heartbreak
After the initial triage (where I validated the findings), the final decision came back from the customer.
Status: Not Applicable / Duplicate
"This issue resides on the GitLab side. Therefore, it is non-applicable."
The Context: The target was running a self-hosted version of GitLab. The vulnerability — the fact that the GraphQL explorer is exposed publicly even on private instances — is a known "feature/issue" in GitLab itself.
Because the vulnerability was in the vendor software (GitLab) and not in the custom code written by the automotive company, they marked it as Out of Scope / N/A.
Phase 6: Why This Still Matters (The Takeaway)
Even though I didn't get paid, this is a critical lesson for Blue Teams and Bug Hunters.
For Hunters:
- Vendor Bugs are Tricky: When hunting on "Commercial Off-The-Shelf" (COTS) software (like Jira, GitLab, Salesforce), known default misconfigurations are often rejected as "Vendor Issues."
- Check the GraphQL: Always check
/-/graphql-explorer,/graphiql, or/v1/graphql. If SSO is misconfigured, this endpoint is often excluded from the auth checks because it's considered a "static asset" or a "developer tool."
For Defenders:
- Defaults are Dangerous: Just because the vendor (GitLab) says "It's a feature," doesn't mean it's safe for your environment. If you host a private instance, block this endpoint at the WAF or Nginx level.
- Defense in Depth: Why was the GraphQL endpoint reachable without a session token? Your SSO layer (e.g., Okta/SAML) should wrap the entire application, not just the UI routes.
Final Score:
- Access: Full Schema & Internal Metadata.
- Bounty: $0 (N/A).
- Lesson: A locked front door means nothing if the API has a public key.
Thanks for reading! If you enjoyed this deep dive, follow me for more stories from the edge of the Bug Bounty world.