
Table of contents
18
Read this in 30 seconds: CVE-2026-97229 is an integer overflow in the regular expression engine that GitLab uses to process CI/CD configuration. GitLab rates it CVSS 10.0 and says it can give an unauthenticated attacker code execution on the GitLab server. CISA added it to the Known Exploited Vulnerabilities catalog on 29 October 2026, with a federal due date of 1 November and a forensic triage flag of “Yes”.
- The fix is in Ruby, not only in GitLab. GitLab’s 12 October releases patch the Ruby that ships in its own packages, and upstream Ruby shipped its fix on 23 October.
- A normal upgrade can leave you exposed. Alpine Linux upgraded GitLab and stayed vulnerable, because its container image used standard Ruby.
- Exploitation is documented. Alpine says an attacker tried it on 20 and 21 October, crashed workers eight times and got partway in, but it found no proof the code ran.
- “Unauthenticated” has a catch. Rapid7 found the attacker still needs to plant a CI configuration in a project, which a self-registered account on many servers can do.
- There is a newer sibling. CVE-2026-110264, also CVSS 10.0, was fixed on 21 October and reaches back to GitLab 7.0, so patch to the latest release, not just 19.4.2.
The lesson of CVE-2026-97229 is that a patched application can still run a vulnerable dependency. The fix lives where most teams do not look, in the language runtime underneath the product.
This article covers what the flaw is, how it works at the level the vendors have published, the timeline, what we know and do not know about exploitation, who is exposed, which version you actually need, and how to check your own GitLab. It does not include exploit code or payloads.

GitLab is written in Ruby, and it takes text from its users and turns it into regular expressions. A CI/CD configuration file, .gitlab-ci.yml, can include patterns, for example to decide which branches or files a job applies to. Ruby’s Regexp.new compiles those patterns into instructions for its regular expression engine, which is called Onigmo.
Compiling a pattern is not the same as matching one. Compiling means parsing text and building an internal program, and any bug in that step touches memory. When the pattern comes from someone else, a memory bug becomes a security bug.
That is the setting for CVE-2026-97229. The code runs inside GitLab’s application workers, so a successful attack lands in the same place as GitLab itself: the server that holds source code, CI/CD variables, runner tokens and integration credentials.
GitLab’s critical patch release page describes CVE-2026-97229 as an issue that, under certain conditions, could have allowed an unauthenticated user to execute arbitrary code on the GitLab server through a specially crafted regular expression in a CI/CD configuration, because of insufficient regular expression validation. CISA’s KEV entry uses the same wording.
Here are the facts, and who said them.
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H), assigned by GitLab as the CNA. The NVD entry, published 13 October 2026, carries GitLab’s score and no separate NVD score.The vendors and researchers do not agree on one word. GitLab and CISA say “unauthenticated”. Rapid7, which reproduced the bug, says an attacker must first be able to commit a CI configuration to a project, and that on servers where new users can self-register and create projects, that condition is easy to meet.
| Source | What it says about who can attack |
|---|---|
| GitLab (CNA) | Unauthenticated user, CVSS PR:N |
| CISA KEV | Unauthenticated user |
| Rapid7 | Needs a way to plant a CI configuration, such as a public project from a self-registered account |
| Alpine Linux (victim) | A newly registered account sent the crafted configurations |
The practical reading is that a server with open registration is exposed to anyone, and a server with closed registration is exposed to anyone who can already create or write to a project. We cannot say that any further restriction fully closes the path.
We are describing this at the level GitLab, Ruby and Rapid7 have published. We are not reproducing an exploit.
Ruby’s advisory says the bug behind CVE-2026-97229 is an integer overflow in the size of a compiled pattern. The change that fixes it is Ruby issue 19020. In plain terms, the engine calculates how big the compiled program will be, the number overflows, and the resulting program is malformed. Ruby’s maintainers say that specially crafted patterns can corrupt memory during compilation.
Rapid7 adds that GitLab’s own validation runs first and accepts the pattern, and the overflow happens later, inside the engine. That is why a check at the application layer did not stop it, and why the fix had to go into the engine.
Two details from Ruby’s advisory change how you should think about defences.
Regexp.timeout does not protect against these bugs, because the problem happens while compiling, not while matching.Why CVE-2026-97229 matters beyond GitLab: the weakness is in Ruby. Ruby’s advisory says any application that compiles a regular expression from attacker-controlled text, through Regexp.new, Regexp.union, Regexp.compile or interpolation into a regexp literal, can reach it. CISA’s KEV note makes the same point, saying other products can potentially be affected by the same underlying issue.
CVE-2026-97229 is one of four GitLab CVEs that all trace to Ruby’s regular expression engine, and all four credit the same researcher. The table below combines GitLab’s and Ruby’s advisories.
| CVE | Bug | GitLab release | Who can attack, per GitLab | CVSS | In KEV? |
|---|---|---|---|---|---|
| CVE-2026-89078 | Double free when a pattern fails to parse | 19.4.1 (23 Sep) | Authenticated | 9.9 | No |
| CVE-2026-93577 | Integer overflow in the compiler | 19.4.1 (23 Sep) | Authenticated | 9.9 | No |
| CVE-2026-97229 | Integer overflow in CI/CD compiler | 19.4.2 (12 Oct) | Unauthenticated | 10.0 | Yes, 29 Oct |
| CVE-2026-110264 | Overflow of internal IDs in a pattern with many repeats | 19.5.1 (21 Oct) | Unauthenticated | 10.0 | No, as of 30 Oct |

Ruby’s advisory says GitLab found these bugs, and that the Ruby releases contain the fixes for the underlying problems. Ruby states that it has not requested CVE identifiers of its own for them yet, so GitLab’s identifiers are the ones to track in a scanner.
Yes, and one victim has described it in detail. The evidence, in order:
What we do not know about CVE-2026-97229 matters just as much.
Our advice is conservative: treat any internet-facing GitLab that was unpatched after 12 October as a possible target, and keep your logs before you patch, because CISA flags this one for forensic triage.
Your exposure to CVE-2026-97229 depends on how you run GitLab, and the trap is the second row.
| How you run GitLab | What you need |
|---|---|
| GitLab.com or GitLab Dedicated | Nothing. GitLab says both are patched. |
| Self-managed with GitLab’s official package or image (Omnibus package or GitLab’s official container image) | Upgrade GitLab. The release carries GitLab’s patch to the bundled Ruby. |
| Self-managed with your own Ruby (source install, third-party or custom container image) | Upgrade GitLab and upgrade Ruby to 3.3.13, 3.4.12, 4.0.9 or later. |
| A server below 19.2 | CVE-2026-97229 does not list it, but CVE-2026-110264 reaches back to 7.0, so you still need to patch. |
| Other Ruby applications that compile user-supplied patterns | Upgrade Ruby. This is the case CISA’s note and Ruby’s advisory describe. |
Alpine’s own report is the clearest example of the second and third rows. Its fix was an upgrade to 19.3.6, which did not help because “the fix isn’t in GitLab’s own code but in a patch to Ruby, which GitLab applies only in its official packages.” Alpine also notes that it had upgraded to 19.3.4 on 13 October instead of 19.3.5, which had the fix, by mistake.
One caution on reading versions. Because GitLab patches Ruby inside its own packages, the Ruby version string inside an official package may not tell you whether the fix is present. This is our reading of GitLab’s and Alpine’s statements, so for official packages go by the GitLab version, and for your own Ruby go by the Ruby version.
To fix CVE-2026-97229, upgrade to the newest patch release for your version, not just the minimum. The minimum fixed versions for CVE-2026-97229 are below. The 21 October releases fix the later CVE-2026-110264 as well.
| Release line | Minimum for CVE-2026-97229 | Also fixes CVE-2026-110264 |
|---|---|---|
| 19.5 | Not affected | 19.5.1 |
| 19.4 | 19.4.2 | 19.4.3 |
| 19.3 | 19.3.5 | 19.3.6 |
| 19.2 | 19.2.8 | 19.2.9 |
| 19.1, 19.0, 18.11 | Not listed | 19.1.9, 19.0.10, 18.11.13 |

Work through it in this order.
Do not rely on the stopgap alone. It limits who can reach the bug on one path, and the vulnerable code stays in place.
These commands check for CVE-2026-97229 by reading versions and looking for signs of worker crashes on your own server. Paths assume a Linux Omnibus install, so adjust them for containers or source installs.
# GitLab and Ruby version information
sudo gitlab-rake gitlab:env:info | grep -iE 'gitlab|ruby'
# Inside a container
docker exec -it <gitlab-container> gitlab-rake gitlab:env:info | grep -iE 'gitlab|ruby'
# Worker crashes around 12 to 28 October (look for segfaults and killed workers)
sudo grep -iE 'segfault|sigsegv|worker .*(killed|terminated|exited)' /var/log/gitlab/puma/puma_stderr.log* /var/log/gitlab/puma/current 2>/dev/null | tail -50
sudo dmesg -T 2>/dev/null | grep -i segfault | tail -20
# Accounts created in the last 45 days
sudo gitlab-rails runner 'User.where("created_at > ?", 45.days.ago).order(:created_at).each { |u| puts "#{u.created_at} #{u.username} #{u.email}" }'
# Recent changes to CI configuration in public projects (adapt to your logging)
sudo grep -h "\.gitlab-ci\.yml" /var/log/gitlab/gitlab-rails/production_json.log 2>/dev/null | tail -50
Interpret the results carefully. A worker crash alone does not prove CVE-2026-97229 was exploited, because other faults also crash workers, and Alpine says a successful exploit leaves no crash at all. A brand new account that shortly afterwards creates projects and commits CI files is a stronger signal.
GitLab also released six threat detections for self-managed customers to spot attempts: Onigmo native worker crash, GraphQL CI lint hostile regexp, CI regexp oversized non-ASCII path, CI regexp guard rejection, CI lint Workhorse worker crash, and CI lint scripted client error burst. If your GitLab or security tooling supports them, turn them on and check what they flagged since 12 October. The 21 October release added detections for CVE-2026-110264, including the same worker crash signal.
Alpine’s report lists what a successful attacker could have reached, which makes a useful rotation checklist for any GitLab server with the same exposure.
Alpine also replaced GitLab’s secret keys, which invalidated passwords, 2FA, tokens and some stored secrets at once. That is disruptive, and you will want a plan before you do it. Anything stored in CI/CD variables should be treated as exposed and rotated at the source system.
Most vulnerability programmes ask “have we patched GitLab?” For CVE-2026-97229 the better questions are “what Ruby is the server actually running?” and “who can put a file into a project on it?”
In an AI-assisted VAPT engagement, that becomes an attack-surface review of your source and CI platform. We check whether registration is open, whether untrusted users can create public projects, what a new account can commit, and whether the patched version is the one actually running, including inside container images. AI vulnerability scanning can help find the GitLab, runner and Ruby instances you forgot about.
Two other things stand out. First, this is the second GitLab bug on the KEV list in seven weeks, after the GitLab path traversal CVE-2026-85706 added on 11 September. We checked CISA’s feed, which lists six GitLab entries in total. Second, another late-October runtime bug is PHP2Shell, and the lesson is the same: a fix has to reach the layer that is actually vulnerable.
A pentest report would not certify that you are safe from this CVE. It documents what was tested and found at a point in time, and you should still patch and verify on your own systems.
Yes. CISA added CVE-2026-97229 to its KEV catalog on 29 October 2026, and Alpine Linux reported that an attacker tried it against its GitLab server on 20 and 21 October. Alpine found no evidence the code ran but could not rule it out, and CISA lists ransomware use as unknown.
GitLab 19.2.8, 19.3.5 and 19.4.2, released on 12 October 2026, fix CVE-2026-97229. Upgrade to the newest patch release for your line instead, because the 21 October releases also fix the related CVE-2026-110264, rated CVSS 10.0 and affecting versions back to 7.0.
GitLab scores it as unauthenticated, but Rapid7 says an attacker must first plant a CI configuration in a project. On a server with open registration, a new account can do that, so treat registration-enabled instances as exposed to anyone and limit who can create or write to projects.
Only if you run GitLab’s official package or image. GitLab fixed it by patching the Ruby it bundles, so a source install or a third-party container with its own Ruby also needs Ruby 3.3.13, 3.4.12, 4.0.9 or later. Alpine upgraded GitLab and stayed vulnerable for exactly this reason.
GitLab says GitLab.com already ran the patched version and GitLab Dedicated tenants were patched before the release, so CVE-2026-97229 requires no action from them. The risk applies to self-managed CE and EE instances.
Check the GitLab version against the fixed list, and if you do not use GitLab’s official packages, check the Ruby version as well. Then read your logs from 12 October onward for worker crashes and unfamiliar new accounts. The NVD entry lists the affected ranges.
CVE-2026-97229 is a Ruby regular expression bug that GitLab exposed to anyone who could get a CI file onto its server, and a documented attack on Alpine Linux shows attackers moved within eight days of the fix. The CISA due date of 1 November has passed, so any server still unpatched is already late.
Patch to the newest GitLab release for your line, check your Ruby if you do not use GitLab’s own packages, and close open registration until you have. If you suspect an attempt, keep the logs, rebuild and rotate secrets. If your team wants someone outside to check what a new account can reach on your GitLab, our AI VAPT services cover exactly that.
Categories
Related articles