GitLab ships out-of-band patches for critical GraphQL flaw allowing unauthenticated project deletion
A 9.4-rated bug reachable without credentials shows why GraphQL authorisation has to live inside every resolver and directive.
GitLab released emergency patches on August 17 for a critical vulnerability in its GraphQL API that could let an unauthenticated attacker modify or delete public projects and associated user data, The Hacker News reported the same day. The flaw is tracked as CVE-2026-19478 and carries a CVSS score of 9.4, placing it near the top of the severity scale. The issue affects both the Community and Enterprise editions.
According to the report, the bug is triggered through a GraphQL directive and under certain conditions allows remote changes without any credentials or user interaction. Affected versions are GitLab Community and Enterprise Edition 18.2 through 18.11.10, 19.0 through 19.0.7, 19.1 through 19.1.5 and 19.2 through 19.2.3. Fixes are available in 18.11.11, 19.0.8, 19.1.6 and 19.2.4. The release arrived outside GitLab's normal patch schedule, a step the company takes for issues it judges too serious to wait.
The same release addressed a second issue, CVE-2026-19650, a high-severity cross-site request forgery weakness in the GraphQL multiplex query handler with a CVSS score of 7.1. Unlike the critical bug, it requires a user to be tricked into performing an action.
GitLab.com and GitLab Dedicated were already patched, so only self-managed installations need to act, The Hacker News said. As of August 18 no public exploit code was known, and GitLab planned to publish full technical details around mid-November, roughly 90 days after the fix, in line with its usual disclosure practice. Administrators running affected versions were advised to upgrade to a fixed release as soon as possible.
Why it matters
Source-code platforms hold the crown jewels of most software organisations, and an unauthenticated path to deleting repositories is about as severe as a web bug gets. The out-of-band release shows vendors now treat API-layer flaws with the urgency once reserved for remote code execution. It also reinforces that self-hosted deployments carry a patching burden hosted customers do not.
Source-code platforms hold the crown jewels of most software organisations, and an unauthenticated path to deleting repositories is about as severe as a web bug gets.
Single endpoint
All queries and mutations arrive at one URL, so there is no route-level gate to rely on.
Directive runs with the query
A directive is code attached to the request that changes how the server processes it.
Missing check in one path
If a resolver or directive assumes authorisation happened upstream, anonymous callers get through.
Fix: enforce in every resolver
Patched versions 18.11.11, 19.0.8, 19.1.6 and 19.2.4 close the path; self-managed instances must upgrade.
What you can learn from this
GraphQL directives are executable hints. In GraphQL, a directive such as
@includeor@skipis an instruction attached to a query that changes how the server processes it. Servers can also define custom directives, and each one is a small piece of code that runs with the query. If that code fails to check who is asking or what it is being asked to touch, a directive becomes a way to reach operations the schema never intended to expose to anonymous users, which is the general shape of this class of bug.Authorisation must be enforced per operation, not per endpoint. REST APIs often protect whole routes, but a GraphQL server exposes one endpoint that accepts many operations in one request. Access checks therefore have to happen inside each resolver and directive, on every field, because there is no route-level gate to rely on. Bugs of this class usually come from one code path that assumed a check had already happened upstream, and they are hard to spot in review because each piece looks correct on its own.
CVSS vectors tell you the attack shape. A score of 9.4 with no privileges required and no user interaction means anyone on the network can trigger the flaw on their own. The 7.1 CSRF bug scored lower mainly because it needs a victim to click something. Reading the vector, not just the number, helps you rank which patch to apply first when several arrive together and which systems are actually exposed. Vectors also record whether the attacker must be on an adjacent network or can reach the target from anywhere on the internet.
Out-of-band patches signal severity. Vendors publish on a regular cadence so administrators can plan downtime; breaking that cadence means the vendor judged the risk too high to wait. The right response is to treat the update as a priority and check whether your instance is reachable from the internet, which determines exposure. Hosted customers were patched by the vendor, which is one of the trade-offs of not self-hosting. Scheduling a maintenance window the same day is usually cheaper than handling an incident later.
Coordinated disclosure delays details. GitLab withholding the technical write-up for roughly 90 days gives administrators time to update before attackers get a blueprint. The absence of a public exploit on day one is not a reason to delay, because working exploits are often reconstructed from patch diffs within days. The window between fix and write-up is the period when patching yields the most protection for the least effort.
We teach this
How to use this in practice
Inventory every self-hosted developer tool you run and its version. List Git servers, CI runners, package registries and wikis, with the current version, who owns it and the date last updated. Compare against each vendor's latest security release and mark any row that is behind. Done looks like a table with no row older than the vendor's most recent security release, saved where the next person can find it. Include the URL of each vendor's security advisory page so the check takes seconds next time.
Find your GraphQL endpoints and test them anonymously. For any service you operate, send an unauthenticated introspection query (
{ __schema { types { name } } }) withcurland note what comes back. If the schema is visible to anonymous users, decide whether that is intended and, if not, disable introspection or put the endpoint behind authentication. Done looks like a note recording which endpoints answer without a token and what mutations they expose. Repeat the query against your staging environment, because the two often drift apart.Add a resolver-level authorisation check to a toy GraphQL API. Stand up a minimal server with one query and one mutation, then write a check inside the mutation resolver that rejects requests lacking a valid user. Try calling it with and without a token, and try a query that uses a built-in directive to confirm the check still runs. Done looks like a passing test for both the allowed and the rejected case. Then move the check into a shared helper so that every future resolver calls it by default.
Write a two-line rule for patch urgency. Decide in advance that any out-of-band vendor release rated critical for internet-facing software gets applied within a fixed window you choose, and record who confirms it. Done looks like the rule written down and applied once to this GitLab release, with the version number recorded after the upgrade and a note of how long the whole process took. Share the rule with whoever else touches the servers.
Sources
- Critical GitLab GraphQL Flaw Could Let Unauthenticated Attackers Delete Public Projects — The Hacker News
Our reporting is an original summary; full coverage is at the links above.
Don't just read about it — build it.
Square 1 teaches the skills behind the headlines, with every line of your work graded by AI. Find your starting point in 3 minutes.
Get your free skill report