Since late September, GitLab has published four critical remote code execution vulnerabilities, each fixed in its own point release. On October 23 the Ruby core team confirmed the source of all four. The bugs are in Onigmo, the regular-expression engine built into the Ruby interpreter, and not in GitLab's code. Ruby 4.0.9, 3.4.12 and 3.3.13 now fix the underlying flaws for everyone else who runs Ruby.
The difference matters. GitLab customers who kept up with that vendor's patches are already covered. Any other Ruby application that turns user-supplied text into a regular expression may carry the same memory-corruption bugs and has had no advisory pointing at it, and Ruby has not requested CVE identifiers of its own for these fixes.
What broke inside the regex engine
A regular expression (regex) is a pattern-matching language, and before Ruby can run one it compiles the pattern into an internal program. According to Ruby's advisory, that compilation step in Onigmo had three separate memory-safety bugs:
- A double free (tracked by GitLab as CVE-2026-89078, fixed in GitLab 19.4.1). The engine releases the same block of memory twice. Attackers can sometimes exploit this kind of bug to corrupt memory in a way they control.
- An integer overflow in the compiled pattern's size (CVE-2026-93577 and CVE-2026-97229). When a number grows past the largest value its variable can hold, it wraps around to a small value. The engine then allocates too little memory for the compiled pattern and writes past the end of it.
- An overflow of internal IDs in patterns with many repeats (CVE-2026-110264, fixed in GitLab 19.5.1). A pattern built with enough repetition runs out an internal counter the engine uses to keep track of its pieces.
The trigger condition is narrow: a regex has to be compiled from attacker-controlled text. Ruby's advisory lists the usual ways that happens: Regexp.new, Regexp.union, Regexp.compile, or interpolating input into a regex literal (a pattern written directly in the source code, such as /#{input}/). An application that only matches user input against fixed patterns written by its developers is not affected by these bugs.
Ruby also warns that two common safeguards do not help here. Regexp.timeout, which limits how long a match may run, and limits on pattern length both act at the wrong layer. The corruption happens while the pattern is being compiled, and, as GitLab's experience shows, a crafted pattern does not have to be long to do damage.
How GitLab got here
According to The Hacker News, GitLab issued the four CVEs between September 23 and October 21. All of them came from one researcher, who goes by joaxcar and reported them through GitLab's bug bounty program.
The severity got worse over that month. The first two advisories, published September 23, required the attacker to have a logged-in GitLab account and were rated 9.9 out of 10. The next two did not. CVE-2026-97229 (October 12) and CVE-2026-110264 (October 21) could be exploited without any account and were rated a perfect 10.0.
The National Vulnerability Database entry for CVE-2026-110264, published October 22, describes the latest one. In GitLab Community and Enterprise Editions, an unauthenticated user could run arbitrary code through an integer overflow while a crafted regex was being compiled. The bug affects every release from 7.0 up to the fixed builds, so it reaches back years. Its CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/S:C) means it can be exploited over the network with low complexity, no privileges and no user interaction. "Scope changed" (S:C) means a successful attack can affect resources beyond the vulnerable component itself.
In short, GitLab compiles regular expressions supplied by its users, such as patterns in CI/CD configuration, and four times in a row the researcher found a pattern that corrupted memory while Ruby compiled it. GitLab shipped each fix by patching the copy of Ruby it bundles. Fixing the root cause for everyone else required a fix in Ruby itself.
Why the Ruby fix needs separate attention
There are three reasons this release can slip past teams that do not run GitLab.
First, the CVE identifiers belong to GitLab. Ruby has not requested CVEs of its own, "at least for now," and says it will update its advisory if it does. A vulnerability scanner that flags Ruby by interpreter version may not connect Ruby 3.4.11 with these four GitLab advisories, so a clean scan does not show that you are safe.
Second, being on a recent Ruby is not enough. The Hacker News reports that Ruby 4.0.8 does not include the fix for CVE-2026-110264. On the 4.0 line, only 4.0.9 contains all of the fixes.
Third, older Ruby branches are left out. Ruby 3.3 normally receives only security maintenance, and the team made an explicit exception to ship these fixes in 3.3.13. Ruby 3.2 reached end of life on April 1, 2026, with 3.2.11 as its final release, according to The Hacker News, and it gets no fix. Ruby 3.2 and earlier will not receive a patch.
As of October 23, none of the four CVEs appeared in CISA's Known Exploited Vulnerabilities (KEV) catalog, according to The Hacker News. The sources do not report any exploitation in the wild. That is reassuring, but it is not a reason to wait: two of the bugs are rated 10.0 and need no login, and their details are now public.
What It Means for Defenders
If you run self-managed GitLab: move to a fixed release on your branch: 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 or 18.11.13. According to NVD, every GitLab CE/EE version from 7.0 up to those builds is affected by CVE-2026-110264. An earlier GitLab patch from September or early October does not cover it. If your instance is reachable from the internet, treat this as an emergency. The two 10.0-rated flaws require no account.
If you run any other Ruby application:
- Upgrade the interpreter to Ruby 4.0.9, 3.4.12 or 3.3.13. Check your container base images, CI images and any Ruby bundled inside vendor appliances, not only the system package.
- If you are on Ruby 3.2 or older, plan a migration to a supported branch. No patch is coming.
- Search your code, and the libraries you depend on, for places where a regex is built from external input. Look for
Regexp.new,Regexp.union,Regexp.compile, and regex literals with interpolated values. Search, filter and highlight features, and admin-defined matching rules, are common places to find them. - Do not count on
Regexp.timeoutor pattern-length caps as mitigations. Ruby says they do not protect against these bugs. - Until you can upgrade, Ruby's only workaround is to stop compiling regexes from untrusted input. Where users only need to search for literal text, use plain substring matching instead of a user-supplied pattern.
For vulnerability management and compliance teams: your scanners may not flag Ruby itself, because these fixes have no Ruby CVEs. Add a manual check for interpreter versions to your asset inventory. Organizations working through CMMC or similar frameworks should record the Ruby upgrade as a separate remediation item, apart from any GitLab ticket, so it does not get closed by mistake when GitLab is patched.
For risk assessment: no source reports these bugs as exploited, and none was in CISA KEV as of October 23. That could change quickly now that the details are public.
Sources
- Ruby: Regexp compilation fixes related to GitLab's CVE-2026-89078, CVE-2026-93577, CVE-2026-97229 and CVE-2026-110264 (Oct 23, 2026)
- NVD: CVE-2026-110264 (read via the NVD CVE API record)
- The Hacker News: Ruby Fixes Three Regex Engine Bugs Responsible for Four Critical GitLab RCE Flaws (Oct 23, 2026)