TL;DR: GitLab fixed two critical GraphQL flaws in self-managed instances, including an unauthenticated code injection path that could alter or delete public projects and a CSRF issue that could let mutations run over GET requests, according to OX Security Platform. The case shows how schema-level features and request handling can become direct integrity failures when validation and execution state drift apart.
At a glance
What this is: OX Security Platform details two GitLab GraphQL vulnerabilities that let attackers tamper with public projects and user data, or bypass intended request protections through multiplexed query handling.
Why it matters: For IAM and security teams, the lesson is that authentication and authorisation controls can fail after the request is accepted if execution context, query validation, and state handling are not tightly bound.
👉 Read OX Security Platform's analysis of the GitLab GraphQL vulnerabilities
Context
GraphQL creates a compact API surface, but that same flexibility can blur the line between query processing and execution. When schema directives, request batching, and fallback behaviour interact badly, an attacker can turn apparently read-oriented mechanisms into state-changing operations. This is a GraphQL security and access-control problem, with a clear identity and privilege angle because the flaws determine who can make changes and under what session context.
In self-managed GitLab deployments, the operational risk is not just vulnerability exposure but governance drift. Security teams need to know which instances are internet-reachable, whether public projects are enabled, and whether the API path sits behind compensating controls. The pattern is typical of modern application security failures: the control exists in principle, but execution assumptions create a gap between policy and reality.
Key questions
Q: What breaks when GraphQL validation and execution use different documents?
A: When validation and execution are detached, the security check no longer applies to the payload that actually runs. That can let a request pass as read-only and later execute a mutation, or let an attacker exploit shared state in a batch. The control failure is request integrity, not just authorization logic.
Q: Why do batching and multiplexing increase API security risk?
A: Batching increases risk because one request can carry multiple operations through shared parsing and execution state. If one operation overwrites context for another, protections based on the original query can be bypassed. Teams should assume every batched operation needs its own independently bound security state.
Q: How should teams reduce GraphQL exposure in self-managed applications?
A: Teams should patch quickly, restrict internet exposure, and test for middleware or tracer behaviour that rewrites documents after validation. Where GraphQL must stay exposed, enforce explicit resolvers, deny-by-default behaviour for missing fields, and logging that ties the validated query to the executed one.
Q: Who is accountable when API compatibility features become security weaknesses?
A: Accountability sits with application owners and platform security teams, because compatibility features are part of the trust boundary once they can affect execution. Frameworks such as the NIST Cybersecurity Framework 2.0 and NIST SP 800-53 both imply that control design must protect integrity all the way through execution, not just at the input layer.
Technical breakdown
GraphQL directive fallback can turn query names into method calls
GitLab’s @gl_introduced directive was designed to smooth rolling upgrades by allowing newer fields to resolve to null on older instances. The weakness emerged in the fallback path: when a requested field was missing, GitLab synthesised a field from the attacker’s supplied name, and graphql-ruby resolved that field by calling the method with the same name on the underlying object. Because the directive was processed before field-level authorization ran, a crafted query could reach state-changing methods instead of a harmless placeholder. The core failure was not parsing alone, but letting attacker-controlled field names influence execution dispatch.
Practical implication: review any GraphQL fallback or compatibility layer that maps user input into runtime method resolution.
Multiplexed queries can create execution state drift
The CSRF flaw came from shared tracer state across multiple queries in one multiplex request. GitLab stored the original document in a single instance variable, then later swapped that document back during execution. In a batch, the last parsed query overwrote the state for earlier ones, so the query that was validated was not necessarily the one that executed. That breaks a fundamental assumption in request security: validation must apply to the exact payload that reaches execution, not to a nearby document in the same batch.
Practical implication: bind validation state to each query object, not to a shared request-level slot.
GraphQL over GET becomes dangerous when read-only checks rely on stale documents
GitLab allowed GET for read-only GraphQL operations and rejected mutations, but that decision was made against the parsed document before execution substitution. If a later step swaps the document, a request that looked safe at validation time can execute a mutation instead. This is a classic request-integrity issue, not just an API bug: the transport method, validation result, and executed document must stay aligned. Without that alignment, CSRF protections can be bypassed even when the application believes it is enforcing method semantics.
Practical implication: test whether GET, batching, and mutation rejection still hold after any middleware or tracer rewrites the document.
Threat narrative
Attacker objective: The attacker aims to alter GitLab data or trigger state-changing operations without valid authorisation, using GraphQL execution weaknesses rather than account compromise.
- Entry occurs through a crafted GraphQL query against a self-managed GitLab instance exposing the vulnerable API surface.
- Escalation happens when fallback logic or multiplexed state handling converts attacker-controlled input into unintended execution behaviour.
- Impact is unauthorised modification, deletion, or mutation of public projects and user data, or request-driven state changes that bypass intended protections.
Breaches seen in the wild
- MITRE ATT&CK Enterprise Matrix — MITRE ATT&CK Enterprise — adversary tactics and techniques, threat detection, attack chain mapping, credential access, lateral movement, privilege escalation.
- Cisco DevHub NHI breach — IntelBroker exploited exposed Cisco credentials, API tokens and keys in DevHub.
Read our 52 NHI Breaches Analysis report for a comprehensive view of breaches impacting Non-Human Identities including AI Agents.
NHI Mgmt Group analysis
Execution-state drift is the real control failure here: the weakness is not simply that GraphQL is complex, but that validation and execution no longer describe the same request. Once a security decision is made on one document and execution happens on another, the control plane has lost integrity. That is an application security failure with direct identity impact, because authorisation decisions only matter if they apply to the executed action.
Compatibility features can become privilege-transfer mechanisms: GitLab’s fallback path was designed to preserve upgrade continuity, but it allowed attacker-chosen field names to influence runtime behaviour. That is a useful reminder for API designers and security architects: resilience features that rewrite or synthesise executable objects must be treated as privileged logic, not convenience code. The practical conclusion is that schema compatibility should never create an implicit path from untrusted input to server-side method dispatch.
GraphQL batching needs a stronger governance model than most teams apply today: multiplexed queries are efficient, but they also create shared-state opportunities that ordinary request controls may miss. This matters for IAM and PAM teams because the security model assumes each request is evaluated independently, while the implementation may reuse context across a batch. Organisations should treat batched API execution as a distinct trust boundary, not a minor transport detail.
Request method semantics are not a sufficient defence when middleware can rewrite execution: the CSRF issue shows why “GET equals safe” is too fragile if the document can be swapped after validation. Security teams need to assume that middleware, tracers, and compatibility layers can invalidate the original decision point. The broader lesson is that API governance must verify the final executable payload, not just the initial request shape.
From our research:
- 71% of NHIs are not rotated within recommended time frames, increasing the risk of compromise over time, according to Ultimate Guide to NHIs.
- From our research: Only 5.7% of organisations have full visibility into their service accounts, according to Ultimate Guide to NHIs.
- From our research: The NHI Lifecycle Management Guide shows how lifecycle controls reduce the exposure window when credentials and service accounts are in play.
What this signals
Execution-state drift: security teams should now treat any middleware that rewrites requests after validation as a governance problem, not just a code issue. The practical signal is that API integrity controls need to follow the final executable payload, especially where GraphQL batching or compatibility features are present.
For IAM and PAM programmes, the key question is whether access and mutation decisions are still anchored to the same transaction. Where the application can swap documents, the access model can be correct in principle and still fail operationally in production. That is why request integrity belongs in the same review cycle as privilege and authentication controls.
Patch cadence matters, but so does exposure mapping. If self-managed platforms expose administrative APIs to the internet, teams should pair vulnerability management with a tighter review of reverse proxies, WAF rules, and logging that can prove which payload actually executed.
For practitioners
- Harden GraphQL fallback paths Inspect any compatibility, future-field, or schema fallback logic for places where attacker-controlled names can be turned into executable server methods. Require explicit resolvers or deny-by-default handling for missing fields, especially where public objects are reachable.
- Bind validation to the executed document Test multiplexed and batched GraphQL requests to confirm that the document validated for method, mutation, and authorization checks is the same document that executes. If middleware rewrites the payload, add integrity checks before execution begins.
- Reassess internet exposure of /api/graphql Inventory every self-managed GitLab instance, confirm whether GraphQL is internet-facing, and place compensating controls such as a WAF or reverse proxy in front of /api/graphql while patching to the fixed releases.
- Patch by branch without delay Upgrade to 18.11.11, 19.0.8, 19.1.6, or 19.2.4, matching the installed branch, because no configuration workaround is documented and the vulnerable behaviour sits in the application path itself.
Key takeaways
- The flaw was a mismatch between what GraphQL validated and what it executed, which let attackers turn compatibility logic into unauthorised state change.
- The incident is a reminder that request batching, middleware rewrites, and fallback dispatch can undermine both authorization and CSRF controls.
- Patch the affected GitLab branches quickly and verify that security checks still apply after any document substitution or execution rewrite.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATT&CK address the attack and risk surface, while NIST CSF 2.0, NIST SP 800-53 Rev 5, CIS Controls v8 and NIST AI RMF set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | TA0001 , Initial Access; TA0040 , Impact | The attack uses remote API exposure and results in unauthorised data alteration. |
| NIST CSF 2.0 | PR.AC-4 | The issue is a failure of access enforcement around state-changing API actions. |
| NIST SP 800-53 Rev 5 | AC-6 | Least privilege is relevant because unauthorised mutations should never inherit broad object-level power. |
| CIS Controls v8 | CIS-16 , Application Software Security | This is an application-layer flaw that needs secure coding and validation practices. |
| NIST AI RMF | GOVERN | The topic is a governance failure in how application trust boundaries are designed and reviewed. |
Map GraphQL exposure and mutation abuse to initial access and impact pathways, then test for execution-state drift.
Key terms
- Execution-State Drift: The gap that appears when the recorded plan and the actual operating reality move out of sync. In practice, it shows up as stale commitments, missed acknowledgements, partial fulfilment, or documentation that no longer matches the current transaction.
- GraphQL multiplexing: A technique that processes multiple GraphQL operations in a single request context. It improves efficiency, but it also increases the chance that shared parsing or tracer state will leak across operations if the implementation does not bind validation and execution per query.
- Fallback field resolution: A mechanism that supplies behaviour when a requested schema field is missing. In secure implementations, fallback should be explicit and constrained. If it instead allows dynamic method dispatch from attacker-controlled names, it can turn compatibility logic into an execution primitive.
- Request integrity: The property that the security decision, validation result, and executed payload all refer to the same transaction. Without request integrity, an application can appear to enforce safe behaviour while a later stage silently changes what actually runs.
What's in the full analysis
OX Security Platform's full analysis covers the operational detail this post intentionally leaves for the source:
- The exact vulnerable GraphQL paths and the code-level fix pattern used to stop method dispatch through fallback fields
- Branch-by-branch patch guidance for self-managed GitLab deployments and exposure checks for /api/graphql
- The tracer state swap sequence that made the CSRF condition possible in multiplexed requests
- Timeline details for the two CVEs and their HackerOne reporting path
Deepen your knowledge
NHI Foundation Level course, the industry's only accredited NHI security programme, covers NHI governance, machine identity security, secrets management, and identity lifecycle controls. It helps practitioners connect access governance to the broader security programme they run across cloud, application, and identity domains.
Published by the NHIMG editorial team on August 19, 2026.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org