News Developer tools

Alpine GitLab attack: the regex fix also needs a patched Ruby

Alpine's GitLab stayed exposed after an upgrade because its own Ruby lacked the fix. If your GitLab runs on a Ruby you supply, upgrade Ruby too.

The short read

Alpine Linux upgraded GitLab twice and was still exposed to a 10.0 flaw, because the fix lives in Ruby.

  • An attacker crashed Alpine's GitLab workers 8 times in October through CVE-2026-97229. Alpine found no sign of success but rebuilt the server anyway.

What you can do with this

If your GitLab is self-compiled or packaged by someone other than GitLab, upgrade Ruby to 3.3.13, 3.4.12 or 4.0.9 as well as GitLab. Then search puma_stderr.log for Ruby [BUG] crash reports.

A dense tangle of blue, white and red network cables hanging down the front of a server rack.
Photo: Kim Scarborough, CC BY-SA 2.0

Alpine Linux disclosed on October 28 that an attacker tried to take over its GitLab server through CVE-2026-97229, a regex flaw rated 10.0. Upgrading GitLab did not close the hole, because the fix is in Ruby, and GitLab ships it only in its own packages. If you host GitLab on any other Ruby, you may be exposed too.

Alpine says, “We have found no evidence that it succeeded, but we cannot rule it out.”

The flaw is the one GitLab patched on October 12: under certain conditions, an unauthenticated user could run code on the server “via a specially crafted regular expression in a CI/CD configuration.” We covered the run of these flaws last week. Alpine’s post is the first public account we have found of someone trying to use one.

Two upgrades, still exposed

Alpine’s timeline shows how the server stayed exposed through two upgrades:

  • October 13: Alpine upgraded to 19.3.4 instead of the fixed 19.3.5, by mistake.
  • October 20 and 21: a newly registered account probed, then sent crafted CI configurations. Worker processes crashed 8 times, with 502 errors and failed CI jobs. In 4 crashes the exploit got partway through.
  • October 22: Alpine moved to 19.3.6. That still did not fix it, Alpine says. The patch sits in a Ruby build that GitLab applies only to its own packages, and Alpine’s GitLab does not run on that build.
  • October 23: the account was blocked and Ruby published its fix.
  • October 27 and 28: GitLab was closed to all but developers and build servers, then rebuilt from scratch.

The attacker also downloaded Alpine’s GitLab container image, which Alpine reads as tailoring the exploit to that build. Alpine says its aports repository and the packages built October 20 to 24 were not tampered with, and its signing keys were never on the GitLab server. It still reset all passwords and replaced GitLab’s secret keys.

Why the GitLab version alone tells you nothing here

The bugs are in Onigmo, the regex engine inside Ruby. Ruby’s own advisory of October 23 says GitLab fixed them by “patching the Ruby it ships,” and that Ruby 4.0.9, 3.4.12 and 3.3.13 “contain all of these fixes.” The same notice went to the oss-security list that day.

So the omnibus package, which carries GitLab’s patched Ruby, is covered. A server on a distribution’s Ruby, a self-compiled install or a third-party image is only as safe as that Ruby. Two more traps: Ruby did not request CVE IDs of its own, “at least for now,” so a scanner that keys on Ruby CVEs may stay quiet. And “Regexp.timeout does not protect against these bugs,” Ruby says.

CISA’s known exploited vulnerabilities feed, released 19:00 UTC on October 28, does not list CVE-2026-97229. That fits Alpine’s account of an attempt with no proven success; it is not a reason to wait.

What to do now

  1. Check who built your Ruby. If GitLab came from GitLab’s own package, the GitLab upgrade covers it. Otherwise, run ruby -v and move to 3.3.13, 3.4.12 or 4.0.9 or later. On Alpine, apk upgrade pulls the fixed package.
  2. Re-pull the Alpine image if you use it: Alpine says alpinelinux/gitlab images pulled before October 27 are vulnerable; pull alpinelinux/gitlab:19.3.6 again.
  3. Search your logs for crashes. GitLab’s Onigmo crash detection looks for a Ruby [BUG] crash report with Onigmo frames such as onig_compile or compile_tree. The file is /var/log/gitlab/puma/puma_stderr.log on the Linux package and /home/git/gitlab/log/puma_stderr.log when self-compiled, per GitLab’s log docs. A grep for onig_compile there is a start.
  4. Treat a clean log as weak evidence. GitLab calls the rule corroborating: a pipeline attack can crash a Sidekiq worker instead, and “the absence of a hit never clears an attempt or a success.”
  5. If you have an Alpine GitLab account, reset the password when the server reopens, and change it anywhere you reused it: Alpine saw automated logins with leaked passwords.

The trade-off is downtime against doubt. Alpine could not prove a break-in, and it rebuilt anyway.

Sources