On 12 October 2026, GitLab shipped a patch for CVE-2026-97229, a CVSS 10.0 unauthenticated remote code execution flaw in the CI/CD regular expression compiler. Four days later, researcher Jonah Burgess published a working CVE-2026-97229 exploit on GitHub — a public proof of concept that runs commands on a vulnerable server as the operating-system git account. If you run a self-managed GitLab instance, the “patch it when you can” window is closed. This is the emergency sequel to our GitLab October 2026 patch guide: what the exploit needs, what it does not prove, and the fastest safe route to patched. Verified and published 21 October 2026.
What the public CVE-2026-97229 exploit does
The PoC (jburgess-r7/CVE-2026-97229-PoC, released 16 October 2026) is a Python script that drives GitLab’s public CI lint endpoint — GET /api/v4/projects/:id/ci/lint — to trigger the integer overflow in the Onigmo regex compiler and redirect VM execution into a system() call, giving command execution as the OS git user. Rapid7’s independent technical analysis, published the same day, confirms the mechanism. This is the same vulnerability our 12 October patch guide covered — back then, there was no public exploit and no confirmed exploitation, and the advice was to patch on your normal schedule. That schedule is now.
The exploit chain, in plain terms:
| Step | What happens | Honest detail |
|---|---|---|
| 1 | Attacker creates an account on the target instance (self-registration is enough where it is open) | Tested against a default Docker deployment |
| 2 | Attacker pushes a branch to a public project — an ordinary project account suffices | This is the prerequisite: push access to a public project |
| 3 | The script calls the CI lint API with a malicious content ref |
The final lint request itself is unauthenticated — no token, cookie, or auth header |
| 4 | The regex compiler overflows; execution lands on system() |
Command runs as the OS git account — full code execution on the box |
| 5 | The request usually ends in HTTP 502 | The worker crashes after the command runs — a 502 alone does not confirm success |
The PoC was tested only against the official Linux amd64 gitlab/gitlab-ce:19.4.1-ce.0 image. Running it against other builds needs adjusted pcode/libruby offsets — so today it is a researcher’s tool, not a point-and-shoot weapon. That said, offsets for other builds are the only missing ingredient, and those are exactly what the public release gives the wider community to compute.
What the PoC does not prove (read this before the upgrade)
A public exploit does not automatically mean mass exploitation, and you should not write that. Here is the honest state as of 21 October:
- No confirmed in-the-wild exploitation. Rapid7, SOCRadar, Help Net Security, and SecurityOnline.info all report none as of this week. One site tags the CVE as “exploited in the wild” with no supporting detail — a single unverified claim, and it stays out of this post.
- The PoC is resource-hungry. The generated pcode is around 2 GiB and the test instance needed roughly 9 GiB of RAM. A small or multi-tenant target may simply crash under the request — denial of service instead of code execution. That makes indiscriminate mass exploitation harder than the CVSS 10.0 number suggests.
- “Unauthenticated” has a footnote. The final lint request needs no token, but the attacker first needs an account with permission to push a branch to a public project. Instances with open self-registration and public projects make that trivial; locked-down internal-only instances do not.
- Not in CISA’s Known Exploited Vulnerabilities catalog. The live KEV CSV was checked on 21 October — no entry, so there is no federal remediation deadline forcing the issue.
And here is the reason to patch today anyway: the previous GitLab CVSS 10.0, CVE-2026-85706 in September, landed in the KEV catalog one day after its patch, with probing reported within hours. This one has not followed that pattern — yet. The gap between “PoC public” and “mass scanning” is where self-managed admins get to act instead of react.
Step 1: Check whether you are exposed (30 seconds)
The vulnerable ranges, confirmed across Rapid7, Censys, and SOCRadar: GitLab CE/EE 19.2 before 19.2.8, 19.3 before 19.3.5, and 19.4 before 19.4.2. Versions before 19.2 are not affected. GitLab.com was patched before disclosure and GitLab Dedicated customers need no action — only self-managed instances.
Find your version one of three ways:
# From the shell of your GitLab server
sudo gitlab-rake gitlab:env:info | grep -i version
# Or check the installed package directly
cat /opt/gitlab/version-manifest.txt | grep gitlab-ce
# Or in the UI: Admin area → Overview → System info
If you are on any branch below the fixed builds, you are exposed. Public exposure matters too: the older your line, the larger the unpatched surface — Censys counted 25,766 internet-facing hosts on vulnerable versions on 13 October (Germany 6,469, Russia 4,173, the US 2,927), with 31% of detected hosts unpatched. Those numbers are stale now, but they tell you the shape of the problem.
Step 2: Patch to the fixed build for your line (5 minutes)
The fixed versions are 19.4.2, 19.3.5, and 19.2.8, all released 12 October. One important nuance: pin 19.3.5, not 19.3.4 — 19.3.4 introduced a separate, non-security issue that breaks merge request pages when the Ona integration is enabled, and GitLab now recommends 19.3.5 instead. Several outlets still cite 19.3.4; they are wrong.
The safe upgrade sequence:
# 1. Back up first. Always. Even on Patch Tuesday urgency.
sudo gitlab-backup create STRATEGY=copy
# 2. Update the package index, then pin to the patched build for YOUR branch
sudo apt-get update
sudo apt-get install gitlab-ce=19.4.2-ce.0 # or 19.3.5-ce.0 / 19.2.8-ce.0
# 3. Reconfigure and restart
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
Omnibus packages for newer major lines exist (19.5.0 shipped 15 October), but whether they carry this fix has not been independently confirmed against the primary source — so pin to the verified builds above unless your line’s release notes say otherwise. If you install from source or use Docker, use the matching tags: gitlab/gitlab-ce:19.4.2-ce.0 and equivalents.
After the upgrade, confirm you are out of the vulnerable range by re-running the version check — and confirm the UI loads and a pipeline still runs before you call it done.
Step 3: If you cannot patch today, buy time with these mitigations
Patching is the fix; these are the stopgaps for the hours between now and your maintenance window. They reduce the two things the exploit needs: an attacker account and a reachable lint endpoint.
- Turn off open self-registration (Admin area → General → Sign-up restrictions). This is the single biggest lever: without a local account, the PoC chain cannot start.
- Move public projects to Internal visibility where you can. The PoC needs a public project the attacker’s account can push to.
- Audit project membership and push permissions on any project that must stay public.
- Block the abused route at your edge (nginx or WAF in front of GitLab) as a last resort. This also breaks legitimate CI lint usage, so treat it as temporary:
location ~ ^/api/v4/projects/.*/ci/lint { return 403; }
Rapid7’s ETR analysis carries further mitigation guidance if your deployment is unusual — link below.
Why the CI lint endpoint was a natural target — and what to harden next
The lint endpoint exists so editors and CI tooling can validate a .gitlab-ci.yml before it ever runs. That means it takes untrusted input, parses it, and evaluates expressions — including the regular expressions that flowed into the vulnerable Onigmo compiler. Any endpoint that evaluates untrusted expressions on the server is a prime RCE candidate; this is the same shape of bug class that keeps showing up in template engines, expression languages, and now regex compilers in CI systems.
Use this PoC as a prompt to harden the deployment itself, not just to patch:
- Do not leave GitLab on the open internet if you do not need to. Put it behind a VPN, a bastion host, or at least an IP allowlist. Every self-managed GitLab that is reachable from anywhere is in the scanning pool.
- Keep sign-ups closed and review dormant accounts quarterly. The PoC’s entry point is an account with push permission — the fewer accounts, the fewer entry points.
- Watch for the next GitLab security round. Singapore’s CSA flagged a separate batch of GitLab CVEs (CVE-2026-6552, CVE-2026-7250, CVE-2026-8589, CVE-2026-10087) on 21 October affecting the 19.0–18.11 lines — a reminder that the patch cadence never stops.
- Test upgrades on a staging copy first if your instance carries custom CI runners or integrations — the 19.3.4 Ona issue is proof that even non-security patch builds can bite.
Step 4: Look for signs someone already tried
Two things to check right now on any instance that was internet-facing and unpatched between 12 and 21 October:
# Lint-endpoint requests from unexpected sources
grep -E "/api/v4/projects/.*/ci/lint" /var/log/gitlab/nginx/gitlab_access.log
# 502s on the lint route — the PoC's tell (not proof of success on its own)
grep -E "ci/lint.*\" 502" /var/log/gitlab/nginx/gitlab_access.log
If you find repeated lint requests from IPs that do not belong to your team, treat the box as potentially compromised: rotate GitLab tokens and deploy keys, audit project access tokens, check for rogue accounts, and consider restoring from a pre-12-October backup plus re-applying the patch. The exploit runs as the git user, so anything that user could touch — repos, CI variables, runner tokens — is in scope for a review.
The bottom line
This CVE-2026-97229 exploit is not yet a worm and not yet in KEV — but it is public, it works, and it targets self-managed infrastructure that holds your source code, your pipeline secrets, and your deployment tokens. The patch has been available for nine days and takes five minutes plus a backup. Close the window yourself, on your schedule, instead of letting an attacker close it on theirs.
Further Reading & References
- CVE-2026-97229 PoC — Jonah Burgess’s public proof of concept (GitHub)
- Rapid7 ETR: CVE-2026-97229 critical unauthenticated RCE in GitLab (mitigation guidance)
- Rapid7 technical analysis: GitLab CI/CD regex integer overflow
- Cyber Security News: public PoC disclosed (16 October 2026)
- Censys advisory: CVE-2026-97229 exposure statistics
- SOCRadar: CVE-2026-97229 critical GitLab RCE (19.3.5 note)
- SecurityOnline.info: GitLab RCE PoC disclosed
- Help Net Security: GitLab CI/CD regex compiler vulnerability
- HowToShipIt: GitLab Security Update (Oct 2026) — the original patch guide



