FR
live

GitLab 19.4.1 closes two CVSS 9.9 RCEs in the CI/CD regex parser

On September 23, 2026, GitLab released a critical patch for 19.4.1, 19.3.3, and 19.2.7, closing two remote code execution flaws at CVSS 9.9 in the pipeline’s regular-expression parser, triggerable by a forged .gitlab-ci.yml file. Any authenticated user who can edit a CI/CD configuration becomes a vector: patch self-managed instances immediately.

A tightly knotted loop of black ethernet cable on a dark desk, a single amber RJ45 connector protruding from the knot.

September 23, 2026. GitLab publishes versions 19.4.1, 19.3.3, and 19.2.7 for Community Edition and Enterprise Edition, calling them a critical patch release. September 23, 2026. Two flaws rated CVSS 9.9 are closed, both in the regular-expression engine that processes CI/CD configurations. September 17, 2026. Version 19.4, released six days earlier, had just extended the control plane to AI agents. Why it matters: a forged regular expression in a .gitlab-ci.yml file becomes a remote code execution primitive, and any authenticated user who can edit a pipeline becomes an attack vector.

Two 9.9s in the same code path

The two critical flaws share a single entry point: the regular-expression engine that validates CI/CD pipeline rules.

CVE-2026-89078 is a double free in the regex parser: under certain conditions, an authenticated user can execute arbitrary code on the server by submitting a specially crafted regular expression in a CI/CD configuration. The CVSS vector is AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:L, a 9.9. CVE-2026-93577 is an integer overflow in the regex compiler, with the same consequence and the same vector but a full integrity-and-availability impact: C:H/I:H/A:H.

Both were reported by the same researcher, joaxcar, through the HackerOne bug bounty program. The affected versions cover all of 19.2 before 19.2.7, all of 19.3 before 19.3.3, and all of 19.4 before 19.4.1 — in other words, nearly every recent self-managed instance.

The regex as an execution primitive

The lesson of this release goes beyond GitLab. A regular expression is not an inert format: compiling and running it means executing a small program, and the historical C-based engines accumulate entire classes of flaws — double free, integer overflow, more rarely direct execution. The fact that GitLab processes regular expressions arriving from CI/CD configuration turns that theoretical risk into a practical vector: .gitlab-ci.yml is written by developers, but it is also editable by any contributor to a project.

Concretely, the exploitation chain reads like this: an authenticated account, even without admin privileges, submits a rule containing a hostile regular expression; the server compiles it while parsing the pipeline; the resulting memory corruption leads to code execution. All without victim interaction and without prior access to the infrastructure.

The rest of the release

The patch also closes several secondary flaws that matter to DevSecOps teams. CVE-2026-84739, a stored XSS in the merge request diff viewer rated 8.7, reaches back to versions 13.11 — a reminder that some flaws sleep for years before being fixed. CVE-2026-92470, rated 7.7, concerns the Duo AI job troubleshooting feature: a missing authorization check let users read sensitive CI/CD variable values from debug-mode job traces. Finally, CVE-2026-92874 fixes a broken scope check on MCP tokens, a direct concern for teams that began wiring AI agents into GitLab with 19.4.

Migrations and the maintenance window

The patch ships with database migrations, which has a concrete deployment consequence. On a single-node instance, the upgrade causes downtime while migrations run, since they must complete before GitLab starts. On a multi-node instance, the zero-downtime upgrade procedures let you apply the patch without an outage, provided you follow them exactly. Versions 19.3.3 and 19.2.7 additionally include post-deploy migrations to run after the upgrade.

For a self-managed Docker instance, the version bump is straightforward:

bash
# Docker (official image) — move up to the critical patch
docker pull gitlab/gitlab-ee:19.4.1-ee.0
docker compose up -d

GitLab.com is already running the patched version, and GitLab Dedicated customers need to do nothing. Self-managed instances carry the risk, and the vendor explicitly recommends upgrading “as soon as possible.”

A vector that comes from “pipeline as code”

The entry point of these two flaws is no accident: it is the CI/CD configuration itself, which has become code in its own right. The only and except rules, workflow:rules, and variable filters all accept regular expressions, and GitLab compiles them every time a pipeline is evaluated. What was once a plain config file has become a server-side attack surface.

This is a broader trend. “Pipeline as code” moved build logic into repositories — great for reproducibility — but it also widened the trust boundary: any contributor to a repository can influence what the GitLab server compiles and runs. A flaw in the parser turns that edit right into code execution, bypassing the runner’s protections entirely.

The mitigation goes beyond the patch. Audit who can edit .gitlab-ci.yml, restrict external contributors to forks without CI access, and watch audit logs for pipelines that are abnormally slow or failing on a regex rule — reflexes that shrink the surface up front, independent of whatever flaws come next. Today’s two 9.9s are a symptom of a surface that will only keep growing.

How to know if you were hit

Before patching, the first question is detection. Exploitation of this class leaves no obvious trace: the code runs inside the GitLab server process, not in an isolated runner, which makes it hard to tell apart from legitimate activity.

The useful signals are indirect. A pipeline failing repeatedly on a regex rule, unusually long or nested regular expressions in recently modified .gitlab-ci.yml files, a sudden spike in server CPU during pipeline evaluation — all weak signals to cross-reference against GitLab audit logs, which record who changed which configuration and when. When in doubt, compare the change history of .gitlab-ci.yml against pipeline error spikes: an exploitation attempt almost always leaves a trace in one of the two.

The conclusion matches any compromise of a DevSecOps control plane: the GitLab server holds the keys to your deployments, your CI/CD secrets, and your source code. Treating it as a critical asset — tested backups, log monitoring, patches within 24 hours — is not optional; it is the minimum bar for a platform that now runs AI agents alongside pipelines.

Verdict

If you administer a self-managed GitLab instance, move to 19.4.1, 19.3.3, or 19.2.7 without delay: two 9.9s exploitable by any authenticated user leave no room for triage. If you run a multi-node instance, plan the zero-downtime upgrade rather than a hard outage, but do not postpone the patch for it. And if prevention is your priority, audit who can edit the CI/CD configuration of your repositories: with this class of flaw, the right to write a .gitlab-ci.yml temporarily equals the right to run code on the server.

References

The cyber brief, every Tuesday

The flaws that matter and the patches to apply, in a ten-minute read.

No spam. One-click unsubscribe.
read next

On the same topic

Docker Engine 29.8.2 fixes a DNS flaw that disables TLS on image registries

The 29.8.2 release closes 14 daemon and BuildKit vulnerabilities, including CVE-2026-92543, which lets a malicious DNS response skip TLS verification or fall back to HTTP during an image pull. Update before your next CI/CD build and pin digests to block image substitution.

Kubernetes 1.38 starts the post-quantum migration with ML-DSA certificates

The v1.38.0-alpha.1 pre-release adds beta support for ML-DSA signing of pod certificates and CSRs, preparing the control plane for the post-quantum era. Enable the CertificateSigningRequestMLDSA feature gate on a test cluster and map your gRPC dependencies before upgrading.

← Back to the feed

Type at least two characters.

↑ ↓ navigate ↵ open esc dismiss