Type
Analysis
Published
Reading time
3 min read
Author
rootzero
Lire en français
Lire en français →

GitLab: when compiling a regular expression can compromise the server

Four GitLab CVEs expose memory corruption in Ruby Onigmo. This analysis separates user input, native compilation, demonstrated impact and patch requirements.

  • GitLab
  • Ruby
  • RCE
  • Vulnerabilities

GitLab fixes: 23 September, 12 and 21 October 2026. Analysis written on 4 November 2026. GitLab’s latest advisory, CVE-2026-110264, has a 10.0 CVSS score. GitLab says a specially crafted regular expression could, under certain conditions, let an unauthenticated attacker execute code on a self-managed server. Three related GitLab identifiers, CVE-2026-89078, CVE-2026-93577 and CVE-2026-97229, also concern memory corruption in Ruby’s Onigmo regular-expression engine. The four numbers do not describe one universal payload.

Why a regex can cross into native memory

A pattern is text, but Regexp.new compiles it into native instructions and tables for groups, repetitions and offsets. Ruby’s security note says GitLab compiles patterns supplied by its users, including CI configuration patterns. A faulty integer used to size or index a compiled structure can wrap, leaving subsequent writes outside the intended allocation. That is a memory-corruption bug in the compiler, not the intended semantics of regex matching.

Ruby identifies three underlying bug families: a double free on parser failure after an alternation, an integer overflow in compiled-pattern size, and an overflow of internal IDs in a pattern with many repeats. CVE-2026-93577 and CVE-2026-97229 map to the same underlying size bug but to different GitLab contexts. CVE-2026-110264 maps to repeat IDs. Fixing one counter cannot be assumed to fix another.

GitLab confirms possible unauthenticated RCE for CVE-2026-110264, but its public notice does not publish the exact anonymous HTTP path, exploit input or end-to-end control-flow chain. The distinction matters: a controlled crash proves availability impact, while RCE requires a demonstrated route from controlled input through corruption to execution. This article does not manufacture a request example from an incomplete advisory.

Discovery and detection

An authorized code review starts at every call that compiles externally controlled regex text, including Regexp.new, Regexp.compile, Regexp.union and interpolated regex literals. Native fuzzing then varies counts, nesting and failure cases against instrumented old and fixed Ruby builds. AddressSanitizer traces can locate the invalid allocation or free; a researcher still needs to connect that crash to a reachable application path. Regexp.timeout does not address compilation corruption, and Ruby warns that pattern-length limits do not reliably block all four bugs. (Ruby analysis)

GitLab published detection material for Onigmo worker crashes and bursts of Org-mode rendering errors. Those are leads for correlation with suspicious requests and changes, not standalone proof that code ran. A compromised GitLab service could expose repositories, CI credentials and deployment artifacts according to the process’s actual privileges; that downstream impact should not be confused with a confirmed compromise of every affected instance.

Fix the runtime that actually executes

The 21 October GitLab patch notice lists fixed releases 18.11.13, 19.0.10, 19.1.9, 19.2.9, 19.3.6, 19.4.3 and 19.5.1. Official packages include the patched Ruby. A custom build with its own Ruby runtime also needs Ruby 3.3.13, 3.4.12 or 4.0.9 or later. GitLab.com was already patched when the notice appeared. Validate the deployed binary and review crash and access telemetry from the exposure period after upgrading.

The broader lesson: text handed to a native compiler is still untrusted input. Its apparent simplicity does not make the compiler memory-safe.

The PHP2Shell analysis provides a comparison with another memory-safety failure: request-state lifetime rather than pattern compilation. When prioritizing fixes on an exposed instance, “CVSS is not risk” separates a technical score from the conditions and consequences of a specific deployment.

Primary sources: GitLab patch release, Ruby’s mapping of the four CVEs to underlying bugs.

#rootzero

A question about your exposure?

Write to us. Someone from the technical team will answer, with sources.