Critical alert · Ruby and GitLab
Ruby Regexp: four critical vulnerabilities disclosed by GitLab.
A crafted regular expression corrupts Ruby's memory while it is being compiled, up to code execution on the server. GitLab is affected, as is any Ruby application that compiles a pattern supplied by a user. Here is how to tell whether you are affected, and how to fix it.
Updated October 23, 2026 · Sources: ruby-lang.org, GitLab
The essentials in 60 seconds
The danger is in Regexp.new.
Only applications that compile a regular expression from text an attacker controls are exposed.
Regexp.timeout doesn't protect you.
Neither Ruby's timeout nor a limit on pattern length stops these bugs: they strike during compilation.
GitLab: update the instance.
GitLab ships its own Ruby. On a self-managed instance, it's the GitLab package that has to be updated.
What's happening
Four memory bugs in regular expression compilation
Numbered and scored by GitLab, which fixed them in its product before Ruby released its own versions.
| CVE | The bug | Access required | CVSS | GitLab fixed in |
|---|---|---|---|---|
| CVE-2026-89078 | Double free in the pattern parser | A GitLab account | 9.9 | 19.4.1 · Sep 23, 2026 |
| CVE-2026-93577 | Integer overflow in the pattern compiler | A GitLab account | 9.9 | 19.4.1 · Sep 23, 2026 |
| CVE-2026-97229 | Integer overflow in the compiler, through the CI/CD configuration | None | 10.0 | 19.4.2 · Oct 12, 2026 |
| CVE-2026-110264 | Integer overflow in the pattern compiler. Affects GitLab 7.0 to 19.5 | None | 10.0 | 19.5.1 · Oct 21, 2026 |
The Ruby team hasn't requested its own CVEs for these fixes yet, and says it may come back to it.
Who is affected
Your Ruby branch, and what to do
Support dates for each branch come from the official ruby-lang.org schedule.
| Branch | Fixed in | Official support | What to do |
|---|---|---|---|
| 4.0 | 4.0.9 | Normal maintenance | Update to 4.0.9 |
| 3.4 | 3.4.12 | Normal maintenance | Update to 3.4.12 |
| 3.3 | 3.3.13 | Security only → Mar 31, 2027 | Update to 3.3.13, a release made as an exception |
| 3.2 and earlier | none | Ended Apr 1, 2026 | Migrate to 3.3 at least, ideally 3.4 or 4.0 |
Ruby 3.2 won't get a fix
Check in 2 minutes
Look in three places: the version, the code and GitLab
The version tells you whether Ruby is patched. The code tells you whether the application compiles patterns that come from outside.
$ cat .ruby-version
$ grep -A1 'RUBY VERSION' Gemfile.lock
$ ruby -v
$ grep -rnE 'Regexp\.(new|compile)|/#\{' app lib
$ sudo gitlab-rake gitlab:env:info | grep -i version
What LibWatch does for you
The Ruby version of every repository, rechecked every night.
- Reads the Ruby version pinned in each repository: .ruby-version, Gemfile.lock, .tool-versions or mise.
- Flags when a newer version of the branch exists, and when the branch is no longer supported, like Ruby 3.2.
- Rechecks everything every night, even projects nobody touches.
Its limit: LibWatch doesn't yet link these CVEs to the Ruby engine, and doesn't monitor the version of your GitLab instance. Also check ruby -v in production.
Your code stays with you: LibWatch reads your dependency files and only keeps the list of your packages. How it works →
Fix
Three steps, and the second is the one people forget
Only updating Ruby fixes all four vulnerabilities.
Update Ruby, then rebuild your images
Also change .ruby-version and the ruby line of the Gemfile, then update Gemfile.lock.
$ rbenv install 3.4.12 && rbenv local 3.4.12
$ bundle update --ruby
$ docker build --pull --no-cache -t mon-app:corrigee .
Restart every Ruby process
Puma, Sidekiq, Solid Queue… A process started before the update still runs on the old Ruby.
$ ps -eo pid,lstart,cmd | grep -E 'puma|sidekiq|solid'
Self-managed GitLab: update the package
To 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 or 18.11.13. Updating the system Ruby doesn't fix GitLab's.
$ sudo apt update && sudo apt install gitlab-ee
# Community Edition: gitlab-ce
In the meantime
If you can't update right away
Protects
Stop compiling patterns that come from users
- — To search for text, String#include? is enough: no pattern is compiled.
- — For a filter, offer a list of predefined patterns rather than an open text field.
# instead of
lignes.grep(Regexp.new(params[:q]))
# prefer
lignes.select { _1.include?(params[:q]) }
Doesn't protect
What doesn't protect you
- — Regexp.timeout: the bugs strike during compilation, before the pattern ever runs.
- — Limiting pattern length: not reliable, according to the Ruby team.
Only the update fixes it
Timeline
One month, from the first CVE to Ruby's fix
Sep 23, 2026
GitLab 19.4.1
First two CVEs fixed, scored 9.9.
Oct 12, 2026
GitLab 19.4.2
A CI/CD vulnerability exploitable without an account, scored 10.
Oct 21, 2026
GitLab 19.5.1
The last CVE, affecting GitLab 7.0 to 19.5, scored 10.
Oct 23, 2026
Ruby 4.0.9, 3.4.12, 3.3.13
The fixes land in Ruby, for every application.
Frequently asked questions