- What: GitLab disclosed CVE-2026-19478, a CVSS 9.4 code injection reachable through a GraphQL directive, and watchTowr confirmed active exploitation against its honeypot network within days.
GitLab CVE-2026-19478 went from public advisory to confirmed in-the-wild exploitation in a matter of days. Preemptive exposure management firm watchTowr reproduced the bug within minutes of disclosure, then observed attackers using it against its honeypot network. The flaw carries a CVSS score of 9.4, requires no credentials, no user interaction, and no obscure configuration, and it lets an unauthenticated attacker rewrite or destroy publicly accessible projects on a self-hosted GitLab instance.
A code injection reachable through GraphQL
GitLab describes the issue as a code injection that can be triggered via a GraphQL directive. The attack surface is the /api/graphql endpoint, which on most self-hosted deployments accepts unauthenticated requests by design so that public project data can be queried. That design choice is what turns a code injection bug into a pre-auth remote data manipulation primitive. If your GitLab instance is internet-facing and hosts any public projects, the preconditions are already met.
The following GitLab Community Edition and Enterprise Edition branches are affected:
- 18.2 before 18.11.11
- 19.0 before 19.0.8
- 19.1 before 19.1.6
- 19.2 before 19.2.4
Fixes shipped in CE and EE 19.2.4, 19.1.6, 19.0.8, and 18.11.11. There is no partial fix and no configuration flag that neutralizes the bug in an unpatched build. Upgrading to one of those four releases is the only durable answer.
The damage is to integrity, not just availability
A repository wipe is loud. You notice it, you restore from backup, you move on. The more dangerous half of this vulnerability is quiet. watchTowr noted that an attacker can delete entire repositories, forge merge records so it appears a fix landed when it did not, and ban project maintainers so they cannot intervene. Those three capabilities chain naturally: silence the people who would notice, alter the record, and let the organization keep shipping on a false assumption.
Consider what a forged merge record does downstream. Your vulnerability management process closes a ticket because the remediation PR shows as merged. Your SOC 2 or PCI evidence package points at the same merge history. Your release notes claim a patched dependency. None of it is true, and nothing in your normal workflow flags the discrepancy, because the system of record is the thing that was tampered with. Backups restore code, but they do not automatically tell you which merge events were fabricated and which were real.
If your GitLab instance ran an affected version while exposed, treat merge records, project membership changes, and maintainer bans from that window as unverified. Reconcile against an independent source: mirror remotes, CI build logs, artifact registries, or signed commits. Do not accept the GitLab UI as proof that a fix landed.
Days, not weeks
Jake Knott, principal security researcher at watchTowr, framed the timeline directly: this is the new reality of vulnerability reproduction and exploitation, where AI-enabled attackers compress the time from disclosure to exploitation, and waiting until the next patch cycle is often too late. That is the operational takeaway. The advisory text plus a diff is now enough raw material for a working exploit in a very short window, and the gap between a public advisory and mass scanning keeps shrinking.
This is not an isolated data point. SAP Commerce Cloud CVE-2026-58231 drew exploitation attempts days after its patch. Attackers moved on a SharePoint authentication bypass immediately after a public proof of concept landed. A monthly or quarterly patch cadence for internet-facing developer infrastructure is no longer a defensible posture for CVSS 9-plus pre-auth bugs.
Hunt for @gl_introduced
watchTowr gave defenders a concrete indicator. Organizations that have not patched should hunt through web logs for requests containing the string @gl_introduced, and look for probes or attempted exploitation. Practical steps:
- Grep NGINX, HAProxy, and load balancer access logs for @gl_introduced, URL-encoded variants such as %40gl_introduced, and any GraphQL directive syntax in POST bodies where body logging is enabled.
- Pull all POST requests to /api/graphql from unauthenticated or unfamiliar source IPs going back to the advisory date, not just the last 24 hours.
- Review the GitLab audit log for project deletions, repository removals, membership changes, and maintainer bans that no one on your team can account for.
- Compare merge request records against CI pipeline history. A merge with no corresponding pipeline run is a strong signal of a forged record.
- Check for new or modified deploy keys, personal access tokens, and webhooks, which are the obvious follow-on persistence targets after any GitLab compromise.
If you cannot patch immediately
GitLab and watchTowr both point at the same stopgaps. Treat them as containment while the upgrade is scheduled, not as a fix:
- Restrict unauthenticated access to /api/graphql at the reverse proxy or WAF layer. Require a session or token before the request reaches the application.
- Remove public repository access entirely, which eliminates the affected condition on public projects.
- Take the instance off the public internet and put it behind a VPN or identity-aware proxy if your team's workflow tolerates it.
- Take a verified out-of-band backup now, before any suspected tampering, so you have a clean reconciliation point.
WAF rules matching on @gl_introduced will catch commodity scanning but not a determined attacker who varies encoding or payload shape. Track the upgrade to 19.2.4, 19.1.6, 19.0.8, or 18.11.11 as the closing action on this item.
What to do this week
Inventory every self-hosted GitLab instance your organization runs, including the ones a single team stood up and never registered with IT. Check the version against the four affected branches. Patch internet-facing instances first, then internal ones, because an internal instance is still reachable from any compromised workstation on the network. Run the log hunt for @gl_introduced across the full window since disclosure, and reconcile merge history for any repository that feeds a production deployment. If you find evidence of exploitation, scope it as a source code integrity incident, not a simple availability event, and validate what actually shipped rather than what your repository says shipped.
Questions about your exposure?
RedEye Security provides assessments for organizations that need to understand their real risk.
Talk to us