Security & privacy

Alpine Linux rebuilds GitLab after critical Ruby regex exploit attempt

Alpine Linux rebuilt its GitLab instance from scratch after an attacker exploited a critical vulnerability in the underlying Ruby engine, highlighting risks in self-hosted CI configurations.

Illustration of a compromised server being rebuilt with secure components
Illustration generated for this article

On October 20 and 21, an attacker targeted the Alpine Linux GitLab instance using a critical vulnerability in the Ruby regular expression engine. Although there is no evidence of successful code execution, the team could not rule it out and chose to rebuild the entire service from scratch to ensure integrity.

What happened

The incident centers on CVE-2026-97229, a critical flaw with a CVSS score of 10.0 that affects how GitLab evaluates regular expressions in CI configuration files. The root cause lies in Onigmo, the regular expression engine embedded within Ruby. GitLab released patched versions on October 12, but these fixes required specific patches to the bundled Ruby runtime rather than changes to GitLab’s own application code. Alpine Linux mistakenly upgraded to GitLab 19.3.4 instead of the fixed 19.3.5 version on October 13, leaving their instance exposed.

Between October 20 and 21, a newly registered account submitted crafted CI configurations designed to trigger the vulnerability. These payloads crashed GitLab worker processes eight times. In four of these instances, the attacker advanced partway through the exploit chain before failing at the subsequent step. The attacker also downloaded the GitLab container image, likely to tune the exploit against the specific build environment. While the team observed no signs of successful code execution, such as unexpected files or process delays, they acknowledged that a successful exploit would leave no trace in standard web logs.

Complicating the response, an upgrade to GitLab 19.3.6 on October 22 did not resolve the vulnerability. Because Alpine’s container image used standard Ruby rather than GitLab’s patched bundle, the underlying flaw remained until Ruby itself released the fix in versions 3.3.13, 3.4.12, and 4.0.9 on October 23. Once the team realized their instance was still vulnerable on October 26, they closed access to everyone except developers and began a full rebuild.

How it works

This vulnerability exploits the way regular expressions are processed by the Onigmo engine within Ruby. When GitLab parses CI configuration files, it compiles these regular expressions. If an attacker provides a maliciously crafted pattern, it can cause the engine to behave unpredictably, potentially allowing for remote code execution. This is not a flaw in GitLab’s business logic but in the foundational language runtime it depends on.

For self-hosted instances, this creates a complex dependency chain. Simply updating the GitLab application is insufficient if the host environment uses a system-wide Ruby installation that has not been patched. GitLab’s official packages include a patched Ruby, but custom deployments or container images that rely on upstream Ruby must wait for the language maintainers to release the fix. In this case, the fix arrived in Ruby releases on October 23, more than a week after GitLab’s initial patch.

Key details

  • Vulnerability: CVE-2026-97229 (CVSS 10.0) in Ruby’s Onigmo regex engine.
  • Attack window: October 20–21, with further attempts on October 25–26.
  • Impact: Eight worker crashes; no confirmed data breach, but treated as compromised.
  • Mitigation failure: Upgrading GitLab to 19.3.6 did not fix the issue because the underlying Ruby was unpatched.
  • Verification: Alpine releases and packages from October 20–24 were verified against external records and found untampered.
  • Response: Full instance rebuild, password resets, and implementation of outbound connection logging.

Why it matters

This incident highlights a critical blind spot in managing self-hosted infrastructure: the distinction between application-level patches and runtime-level fixes. Developers often assume that upgrading the primary software package resolves all associated security risks. However, when vulnerabilities exist in shared dependencies like Ruby, Python, or Node.js, the remediation path is fragmented. Teams must track patches across multiple layers, including the language runtime, the operating system packages, and the application itself.

For engineering leads, this underscores the importance of verifying the composition of container images and deployment artifacts. Relying on default system packages can introduce lag between a vendor’s fix and your environment’s security posture. Additionally, the lack of outbound network logging hampered the investigation, demonstrating that visibility into egress traffic is just as vital as ingress monitoring for detecting exfiltration or command-and-control activity.

What you can do

  • Verify your Ruby version immediately; ensure you are running 3.3.13, 3.4.12, 4.0.9, or later if you use GitLab.
  • Check your GitLab container images; if you pulled alpinelinux/gitlab:19.3.6 before October 27, pull it again to get the patched Ruby.
  • Audit your CI/CD pipelines for any recent changes or failed jobs that might indicate probing attempts.
  • Enable logging for outbound network connections from your CI servers and database hosts to improve incident response capabilities.
  • Reset all passwords and rotate secrets, including CI/CD variables and runner tokens, if you suspect exposure.
  • Implement signed release tags for your internal artifacts to allow independent verification of build integrity.
  • #security
  • #gitlab
  • #ruby
  • #devops
  • #incident-response

Tools from the Bytechap store

Keep reading

All stories