GitLab patched CVE-2026-97229 on October 12. Three weeks later it’s being exploited in the wild, and one of the best-documented targets, Alpine Linux, shows a trap that self-hosters can easily fall into: you can upgrade GitLab to a “fixed” version and still be vulnerable.
The bug
GitLab’s advisory describes an integer overflow in the CI/CD regular expression compiler that “could have allowed an unauthenticated user to execute arbitrary code on the GitLab server via a specially crafted regular expression in a CI/CD configuration.” It’s rated CVSS 3.1 10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H), and was reported by researcher joaxcar through HackerOne.
Rapid7 reproduced the full chain against the official GitLab 19.4.1 CE image with ASLR enabled. The mechanics:
- A crafted regex first compiles in a compact US-ASCII form and passes GitLab’s validation.
- When it’s evaluated against a specially formed UTF-8 repository path, Ruby’s Onigmo engine recompiles it for the new encoding, after the checks have already run.
- An integer overflow in the program-size calculation produces invalid regex VM instructions, which can be steered into running an OS command as the GitLab
gituser.
Rapid7 adds one caveat to “unauthenticated”: the attacker needs a way to commit a malicious .gitlab-ci.yml and a UTF-8 repository path to a public project. On instances that allow self-registration and project creation, that’s just an ordinary account.
Now exploited
On October 29, CISA added CVE-2026-97229 to its Known Exploited Vulnerabilities catalog and gave federal agencies until Sunday to patch. BleepingComputer reports that Shadowserver tracks nearly 2,800 internet-exposed GitLab CE instances. GitLab also published six threat detections for self-managed customers, including “Onigmo native worker crash” and “ci lint workhorse worker crash.”
| GitLab CE/EE | Fixed in |
|---|---|
| 19.2 before 19.2.8 | 19.2.8 |
| 19.3 before 19.3.5 | 19.3.5 |
| 19.4 before 19.4.2 | 19.4.2 |
GitLab.com and GitLab Dedicated are already patched.
The Alpine lesson: the fix lives in Ruby
Alpine Linux’s incident report, published October 28 and covered by BleepingComputer on November 1, is worth reading in full. The short version:
- On October 13, Alpine upgraded to 19.3.4 instead of 19.3.5 by mistake.
- On October 20–21, a newly registered account sent crafted CI configs. GitLab workers crashed 8 times, and in 4 of those the attacker got partway through the exploit. They also downloaded Alpine’s GitLab container image, which suggests they were tuning the exploit to that exact build.
- On October 22, Alpine upgraded to 19.3.6, and that still didn’t fix it. GitLab’s release notes show why: the fix is listed as “Add Ruby regexp program size patch for 3.3 and 3.4.” It’s a patch to the Ruby that GitLab bundles in its own packages and images. Alpine’s image used standard Ruby. Upstream Ruby shipped the fix on October 23 in 3.3.13, 3.4.12 and 4.0.9.
Alpine found no evidence of code execution and no tampering with aports, packages, or the October 21 releases, and signing keys were never on the GitLab host. But some logs were gone and there was no record of outbound connections, so the team couldn’t rule out a compromise. They rebuilt the instance from scratch, reset every password, replaced GitLab’s secret keys, and reopened on 19.3.7.
Alpine also notes that the underlying bug is in Ruby’s regex engine, so any Ruby program that compiles regexes from untrusted input is exposed, not just GitLab.
What to do
- Official Omnibus/Helm/Docker packages: upgrade to 19.2.8, 19.3.5, 19.4.2 or later now, outside your normal patch cycle.
- Source installs or custom images: check the Ruby your GitLab actually runs (
ruby -vinside the container). You need 3.3.13, 3.4.12, 4.0.9 or later as well as a fixed GitLab version. - Using
alpinelinux/gitlab: pullalpinelinux/gitlab:19.3.6again. Only the image published on October 27 (Ruby 3.3.13) is fixed. - Until patched: restrict anonymous access to public projects, turn off open sign-up, and stop untrusted users from creating or writing to public projects. Rapid7 notes this only blocks the demonstrated delivery path.
- Hunt: look for GitLab worker crashes and CI lint errors since mid-October. If you find them on an unpatched instance, follow Alpine’s playbook and rotate CI/CD variables, runner tokens, and integration credentials.
- Other Ruby services: update Ruby anywhere you compile user-supplied regexes.
For related CI/CD advisories, see our Jenkins October advisory breakdown and the security tracker.