Patching GitLab Was Not Enough: Alpine’s Near-Miss With CVE-2026-97229
On 28 October 2026 Alpine Linux disclosed that an attacker tried to exploit CVE-2026-97229 — the CVSS 10.0 unauthenticated RCE in GitLab CI-configuration regex handling at the centre of the 12 October critical patch — against its own GitLab server on 20–21 October, a week after the fix shipped. The attack came close, Alpine says; with no evidence of success but no way to rule it out, the team rebuilt the instance from scratch. We read Alpine’s incident report first-hand, in full. Then, on 29 October, CISA added CVE-2026-97229 to its Known Exploited Vulnerabilities catalog with a 1 November remediation deadline — confirmed against the live KEV feed, not a secondary. And the detail that earns this story its place on this site: when Alpine’s 22 October GitLab upgrade silently left the server exposed, it was an LLM agent that noticed, lead developer Natanael Copa told RuntimeWire.
How the attack unfolded
Alpine calls its starting position a mistake: on 13 October it upgraded to GitLab 19.3.4 instead of the fixed 19.3.5, so the server still lacked the 12 October fix when a newly registered account began probing it on 20 October. The account sent crafted CI configurations on 20 and 21 October that crashed GitLab worker processes 8 times; in 4 of those crashes the attacker got partway through the exploit before failing at the next step. The main 21 October push also caused 502 errors and failing CI jobs. The attacker downloaded Alpine’s GitLab container image mid-campaign — “suggesting they were tuning the exploit to our exact build.” Alpine blocked the account on 23 October; the attacker returned on 25 and 26 October and failed to get back in.
On forensics, Alpine is admirably blunt about what it cannot prove. Timing probes showed no delays, and there were no unexpected files, keys, hooks, or processes, nor any private data observably exfiltrated — but “a successful exploit would leave no crash and no trace in the web logs,” and the evidence that could settle the question no longer exists: background job logs and the old container filesystem are gone, and neither Alpine nor its hosting provider logged outbound connections. So the instance was treated as compromised: closed to everyone but developers and build servers on 27 October, rebuilt by the 28th, secret keys replaced, every account password reset. If the attack had succeeded, the exposure list is sobering: user emails, names, and IPs; password hashes; 2FA secrets; CI/CD variables and runner tokens; webhook, integration, and push-mirror credentials; hashed personal access tokens; private repositories and confidential issues and merge requests. Alpine has not said whether runner tokens, variables, and integration credentials beyond passwords and server keys have been rotated — an open question worth pressing if you mirror their infrastructure.
The upgrade that fixed nothing — and the agent that caught it
The root cause is a layering trap. The bug is in Onigmo, the regex engine inside Ruby; GitLab’s 12 October fix is a set of patches to the Ruby GitLab bundles in its own packages and container images. Alpine’s image uses standard Ruby, so upgrading the server to GitLab 19.3.6 on 22 October changed GitLab without changing the vulnerable Ruby underneath. Asked by RuntimeWire what tipped the team off that the upgrade had left them exposed, Copa answered: “LLM agent.” An AI agent, not a person, flagged the residual exposure — the defensive mirror of the agentic-offense stories that dominate this feed, and a concrete data point for agent-assisted patch verification. The fixed image (republished 27 October, embedding Ruby 3.3.13) closes it; users of Alpine’s container image must pull alpinelinux/gitlab:19.3.6 again rather than assume the tag they hold.
For everyone running GitLab on their own Ruby — from source or in a self-built image — the rule Alpine states is absolute: upgrading GitLab is not enough; Ruby itself must go to 3.3.13, 3.4.12, 4.0.9, or later. Ruby 3.2, still listed as the minimum in GitLab’s self-compiled installation guide, reached end of life in April and will never be fixed. As of 29 October, The Hacker News reports, neither of GitLab’s patch-release posts tells self-compiled administrators to update Ruby — a documentation gap that leaves exactly the fleet most likely to be exposed believing it is patched. Rapid7’s working exploit and proof-of-concept, published 13 October, sharpens the urgency: it ran commands as GitLab’s git user on unpatched official 19.4.1, needs write access (a malicious .gitlab-ci.yml plus a UTF-8 path on a public-project branch), but that prerequisite evaporates on servers where anyone can register and create projects.
The supply chain held — this time
Alpine’s report doubles as a case study in verifying build integrity under pressure. Every aports change added 20–22 October arrived through a recorded push by a known developer, checked against records the attacker could not reach — a developer’s repository copy and all 45 build servers — and every package built 20–24 October traces to aports as published on git.alpinelinux.org, including the 21 October releases and their minirootfs files. Package-signing keys never lived on the GitLab server. Checks are being extended through 27 October, when the server was closed. That is the standard every distro and every team with a self-hosted forge should be able to meet — and most cannot.
What to do
- Meet the 1 November KEV deadline: CISA’s 29 October listing of CVE-2026-97229 (alongside Cisco’s CVE-2026-76418) gives federal systems three days; treat it as everyone’s deadline given the public Rapid7 exploit and a confirmed in-the-wild attempt.
- Patch the Ruby, not just the app: on any self-compiled or self-imaged GitLab, upgrade to the newest release for your branch and Ruby to 3.3.13, 3.4.12, 4.0.9, or later. Anything still on Ruby 3.2 must migrate — no fix is coming.
- Re-pull, don’t assume: container tags you already hold may predate the fixed Ruby; re-pull
alpinelinux/gitlab:19.3.6(27 October build) and audit your own image the same way. - Restrict open registration and untrusted write access to public projects if you cannot upgrade immediately, per Rapid7’s interim guidance — the exploit’s write prerequisite is the only thing standing between scanners and RCE.
- Verify your build chain like Alpine did: recorded pushes, an unreachable second copy of the source tree, and package-to-source reconciliation over the exposure window.
Our write-up is analysis of Alpine Linux’s 28 October 2026 incident report (read first-hand in full), the live CISA KEV catalog CSV (confirming the 29 October addition of CVE-2026-97229 with a 1 November due date, read first-hand), Natanael Copa’s “LLM agent” statement as reported by RuntimeWire on 29 October (read first-hand), and The Hacker News’ 29 October account (read first-hand) for the Rapid7 exploit details, the attacker timeline, and the GitLab documentation gap, carried with attribution. The 12 October patch itself is not restated beyond what the new developments require — see the linked briefing. All verification was read-only: we ran no exploit, probed no GitLab instance, and contacted no party.
Sources:
- Alpine Linux — “GitLab security incident: attempted exploitation of CVE-2026-97229” (28 October 2026; attack timeline, crash counts, rebuild and reset scope, Onigmo/Ruby root cause, aports verification)
- CISA — Known Exploited Vulnerabilities catalog (live CSV; CVE-2026-97229 added 29 October 2026, due 1 November 2026)
- The Hacker News — “Attacker Tried to Exploit Alpine Linux’s GitLab via CVSS 10.0 Flaw Its Ruby Left Open” (29 October 2026; Rapid7 exploit and PoC, write-access prerequisite, GitLab documentation gap, remediation matrix)
- RuntimeWire — “An AI agent caught that Alpine’s GitLab upgrade hadn’t closed a critical hole, its lead developer says” (29 October 2026; Copa’s “LLM agent” statement)