Note: articles are for educational purposes and are not professional security advice — consult an expert for your specific needs.

CVE-2026-97229: GitLab update missed the Ruby fix

In short

Alpine’s GitLab 19.3.6 upgrade left CVE-2026-97229, an integer overflow in Ruby’s Onigmo regex engine enabling unauthenticated RCE, unpatched. Official GitLab fixes are 19.2.8, 19.3.5 and 19.4.2; custom images also need Ruby 3.3.13, 3.4.12, 4.0.9 or later. Alpine’s 19.3.6 images pulled before October 27 remain vulnerable and must be pulled again.

Summary written with AI from this article, and checked against it.

A protected server with a cracked inner gear shows how a GitLab update left its Ruby runtime vulnerable.

At a glanceCVE-2026-97229

CVE-2026-97229 has a CVSS 3.1 base score of 10.0 (Critical) from GitLab. It is fixed in GitLab 19.2.8, 19.3.5 and 19.4.2.

Severity10.0 Critical (CVSS 3.1, GitLab)
Fixed inGitLab 19.2.8, 19.3.5, 19.4.2
AffectedGitLab 19.2.0 – before 19.2.8; 19.3.0 – before 19.3.5; 19.4.0 – before 19.4.2
ExploitedYes: in CISA's Known Exploited Vulnerabilities catalog since October 29, 2026
EPSS27% chance of exploitation in the next 30 days (FIRST, November 1, 2026)
Public exploit6 GitHub repositories name it: proofs of concept, scanners, detections. Unverified: some are fake or malicious.
VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
WeaknessCWE-190 Integer Overflow or Wraparound
Ubuntu16.04 xenial gitlab: Won't be fixed
Debianbookworm, bookworm ruby3.1: Vulnerable · trixie ruby3.3: Vulnerable · forky, sid ruby3.3: Vulnerable
Red HatRHEL 10: Affected, RHEL 10: Affected, RHEL 6: Affected

Is there a public exploit for CVE-2026-97229?

Yes: CVE-2026-97229 is exploited in the wild. CISA added it to its Known Exploited Vulnerabilities catalog on October 29, 2026. 6 public GitHub repositories name it: proofs of concept, scanners and detections. None of it is verified: some such repositories are fake or carry malware, so read the code before running it, and only against systems you own. FIRST's EPSS puts the chance of exploitation in the next 30 days at 27%, higher than 98% of scored CVEs.

From NVD, Ubuntu, Debian, Red Hat · checked November 2, 2026

Alpine upgraded GitLab to 19.3.6 and the vulnerability was still there. CVE-2026-97229 hits GitLab 19.2.0 through 19.2.7, 19.3.0 through 19.3.4, and 19.4.0 through 19.4.1, per NVD's record. The fixed releases for the official builds are 19.2.8, 19.3.5 and 19.4.2. Custom images also need a patched Ruby. Verify both pieces before you call the upgrade done; here's how to separate patching from recovery.

BleepingComputer reports that attacks on October 20–21 forced Alpine to rebuild its GitLab server and reset every password. That server hosts development repositories, code reviews, and build jobs — including the aports recipes that produce Alpine packages. For anyone running services on Alpine-based containers, this became a supply-chain concern, not just a GitLab availability problem.

Check GitLab's Ruby before accepting the fix

Alpine's incident report nails the distinction: GitLab shipped the fix for CVE-2026-97229 as patches to its bundled Ruby. Alpine's custom image used standard Ruby, so those patches never arrived when GitLab got upgraded. The GitLab version number alone didn't tell you whether you were actually patched.

  1. Identify whether the deployment uses GitLab's official packages or images, or a custom build with separately supplied Ruby. Use the fixed GitLab releases 19.2.8, 19.3.5 and 19.4.2 for the official-package check.
  2. For a custom build, inspect the Ruby version included in the deployed environment. Alpine says these installations also need Ruby 3.3.13, 3.4.12, 4.0.9 or later.
  3. If you use Alpine's image, pull alpinelinux/gitlab:19.3.6 again. Alpine says the image published on October 27 contains Ruby 3.3.13; images bearing that tag pulled before October 27, and all older tags, remain vulnerable.
  4. If the relevant Ruby installation comes from Alpine packages, apply the package upgrade Alpine recommends.

For Alpine-packaged Ruby, this is the published upgrade command:

apk upgrade

This is an upgrade command, not a version-inspection command; it does not establish whether a separately built GitLab image contains the repair. Check the runtime actually included in the deployed image before closing the patch task instead of accepting the image tag as sufficient evidence.

GitLab security at a glance: Custom images also need a patched Ruby; Check the runtime actually included in the deployed image; Package integrity was checked outside GitLab; Those checks found no tampering

How CVE-2026-97229 survived a GitLab upgrade

CVE-2026-97229 sits in Onigmo, Ruby's regex engine — an integer overflow. GitLab evaluates regexes from pipeline configs, so there's a straight line to the vulnerable code. NVD lists GitLab's rating of 10.0 Critical on CVSS 3.1: unauthenticated RCE.

GitLab published fixed releases on October 12. Alpine mistakenly installed 19.3.4 instead of 19.3.5 on October 13. After the attack, its October 22 upgrade to 19.3.6 still left the separately supplied Ruby unpatched. Upstream Ruby released its fixes on October 23.

Alpine counted eight worker crashes across the October 20–21 attempts. Four of them showed the attacker getting partway through the exploit chain before hitting a wall. The attacker also pulled Alpine's GitLab container image — the project says that hints at prep tailored to their exact build. Plausible, not confirmed.

CISA added CVE-2026-97229 to its Known Exploited Vulnerabilities catalog on October 29. That proves exploitation in the wild, but it doesn't prove Alpine's server was successfully exploited. I'd prioritise the patch check on a running GitLab service without turning CISA's broader finding into a claim Alpine itself couldn't confirm.

Alpine's rebuild followed two unsuccessful patch decisions

Its October 30 update confirms GitLab is open again; the timeline dates reopening to October 29, with GitLab upgraded to 19.3.7.

DateEvent reported by Alpine
October 24Alpine checked aports, packages and the October 21 releases against external records.
October 25–26The attacker returned, but attempts to regain access failed.
October 26Alpine discovered that the upgraded instance remained vulnerable.
October 27Access was limited to developers and build servers, and rebuilding began.
October 28The rebuild finished; passwords were reset and GitLab's secret keys replaced.

Package integrity was checked outside GitLab

Alpine didn't trust the potentially compromised server to validate its own packages. They checked aports commits against external records, comparing them to a developer's clone and to the records from all 45 builders, which provided independent verification. Every commit added Oct 20–22 came through a recorded push from a known developer.

They also checked every package built from October 20 to 24, across every architecture, against commits published on git.alpinelinux.org. The October 21 stable releases came from those same verified commits, including their installation images and the minirootfs archives used for official Alpine Docker images.

Those checks found no tampering. Separately, Alpine says package and release signing keys were never stored on the GitLab server, so those keys weren't exposed there. The GitLab secret keys replaced during rebuilding shouldn't be confused with Alpine's package-signing keys.

For anyone deciding whether the CVE-2026-97229 incident proves an Alpine container supply-chain compromise, that distinction matters: Alpine found no such tampering in the material it checked.

Missing logs leave Alpine's compromise status unresolved

Alpine found no evidence that attacker-controlled code executed via CVE-2026-97229. Timing probes showed no delays. Investigators found no unexpected files, keys, hooks, or processes. They also saw no private data returned through the web or API requests available for inspection.

However, Alpine says a successful exploit would leave neither a crash nor a trace in the web logs. Background-job logs and the old container's filesystem were gone, and neither Alpine nor its hosting provider had outbound-connection logs. No observed success was not enough to rule out success.

“Because we cannot rule out code execution, and the evidence we would need to confirm it no longer exists, we took the harder route and rebuilt the GitLab instance from scratch.”

— the Alpine Linux team

The verification window also needs care. Alpine performed its integrity checks on October 24, while GitLab remained vulnerable until access was restricted on October 27. Its notice says checks were being extended to that date; it does not report that extension as complete.

If exploitation succeeded, Alpine says potentially exposed material included:

  • User names, email addresses, IP addresses and password hashes.
  • Two-factor authentication secrets, pipeline variables and runner tokens.
  • Webhook, integration and push-mirror credentials.
  • Private repositories, confidential issues and confidential merge requests.

These are possible exposures, not confirmed theft. Rebuilding addresses a possible foothold on the old server; it doesn't answer whether information had already left it.

Reset Alpine GitLab access and review reusable secrets

Alpine reset every GitLab password. Account holders need to set a new password through "Forgot your password?" on the sign-in page. If that password was reused elsewhere, Alpine explicitly advises changing it there too. The project also reports automated login attempts using passwords leaked from other sites.

Teams with secrets stored in Alpine's GitLab should review the potential-exposure categories above and replace runner tokens and integration credentials as needed. That's a precautionary recommendation, not a claim that Alpine confirmed those secrets were taken. A password reset alone shouldn't be treated as a decision about runner tokens or integration credentials.

Alpine's reopening update also points users to new SSH host-key fingerprints. Use the project's published fingerprints when checking the rebuilt service rather than assuming the old server identity still applies.

Make the runtime part of GitLab patch acceptance

Alpine says its response includes applying critical GitLab security releases within a day and checking each release for Ruby or other component patches its custom build must carry. It also lists outbound-network and database-connection logging, retention longer than 14 days, and signed release tags among its changes. Read those as the project's stated response, not proof that every measure is already deployed.

For CVE-2026-97229, my recommendation is to require evidence of both the fixed GitLab release and the repaired runtime before accepting a custom-image upgrade. The related Ruby 4.0.9 security fixes are relevant to that runtime review. Alpine's incident shows why an application release number can look reassuring while the component carrying the actual repair remains unchanged.

FAQ

Frequently asked questions

Which October 21 Alpine releases did the project verify?

Alpine names stable releases 3.21.9, 3.22.7, 3.23.7 and 3.24.3. It says they were built from the same aports commits checked against records outside GitLab.

Were Alpine GitLab personal access tokens stored in plaintext?

Alpine lists personal access tokens as stored as hashes. They are included among information that could have been exposed if exploitation succeeded; the project has not confirmed that exposure.

Is public exploit code listed for this vulnerability?

PoC-in-GitHub lists six GitHub repositories naming CVE-2026-97229 in the November 2 data. Those entries are explicitly unverified, so the count should not be read as six independently confirmed working exploits.

Sources

Primary sources

  1. Write-upGitLab security incident: attempted exploitation of CVE-2026-97229 · alpinelinux.org
  2. Write-upEnterprise Email Security Assessment · adaptivesecurity.com
  3. CVE recordNVD and distribution data for CVE-2026-97229 (checked 2026-11-02) · nvd.nist.gov

Reports of the story

  1. News reportAlpine Linux rebuilds GitLab after attempted RCE attack · bleepingcomputer.com

How this article was made: drafted with AI from the sources above and fact-checked against them, then reviewed by Vishal on . How we write and check articles.

Vishal

About the author

· Software & security engineer

GitHub · LinkedIn · X

Vishal writes Trickyworld's tutorials and interview-preparation guides on programming, databases, cyber security and AI. Vishal has been shipping production software long enough to have firm opinions about Python, PHP, Node.js, and JavaScript, and to have been wrong about each of them at least once. The work has run the whole stack: Drupal and Laravel applications, React front ends, MySQL and MongoDB underneath, Redis and Memcached for the things that had to be fast, Apache Solr for the things that had to be findable. That last part turned out to matter more than anyone expected. Tune a Solr index for a season, then watch a language model confidently retrieve the wrong document, and you recognise an old problem wearing new clothes. Most of what is hard about AI systems is not the model. It is retrieval, caching, latency budgets, and deciding what the system does when the answer comes back wrong — which is work he has been doing since well before anyone called it AI engineering. He plays a lot of games, which is less a hobby disclosure than an admission of where a good share of his engineering instinct came from. Real-time systems with a frame budget. State that has to stay coherent while a player does something no designer anticipated. The permanent question of what happens when the frame cannot finish in time. Those habits carry over more directly than they have any right to. He has written several books on programming, all built on the same conviction: most technical writing is unclear because the author never decided what to leave out. More from Vishal → · Editorial policy

More on Cyber Security.

Latest articles

$ subscribe --weekly

Get the next tutorial in your inbox.

Programming, security and AI — the practical bits, no spam. Unsubscribe any time.