3 November 2026 · Siber güvenlik
Why Alpine Linux rebuilt its GitLab from scratch: CVE-2026-97229 and lessons for self-hosted CI
GitLab's CVSS 10.0 flaw CVE-2026-97229 is now being exploited in the wild. Alpine Linux's candid incident report shows exactly what teams running their own GitLab should be checking.
If you run GitLab on your own servers, the last three weeks have probably kept you busy. CVE-2026-97229, a CVSS 10.0 flaw patched on October 12, is now being actively exploited. CISA added it to its Known Exploited Vulnerabilities (KEV) catalog at the end of October, and over the weekend Shadowserver reported tracking more than 1,000 internet-facing GitLab instances that are still unpatched.
What makes this more than another patch-now story is the incident report published by Alpine Linux. Alpine believes the attacker most likely failed. But because it could not rule out code execution, it rebuilt its GitLab server from the ground up. The report is unusually candid about both the mistakes and the decisions that paid off, and that is what makes it worth reading.
What is the vulnerability?
According to GitLab, it is an integer overflow in the component that compiles regular expressions found in CI/CD configuration. Under certain conditions, a crafted regex can lead to code execution on the GitLab server.
- Affected: 19.2 before 19.2.8, 19.3 before 19.3.5 and 19.4 before 19.4.2 (Community and Enterprise Edition).
- Not affected: GitLab.com and GitLab Dedicated are already patched. This is a self-managed problem.
- In practice: GitLab classifies the bug as exploitable without authentication. Rapid7, which reproduced it, says the attacker needs to push a malicious
.gitlab-ci.ymlto a branch in a public project. On instances where any user can create public projects, an ordinary account is enough. If sign-up is open, there is very little standing in the way.
The root cause is the important part. The bug is not in GitLab's own code but in Onigmo, the regex engine inside Ruby. GitLab's fix is effectively a Ruby patch, and it only ships in GitLab's official Linux packages and container images.
On October 21, GitLab patched a second critical flaw in the same area, CVE-2026-110264. It affects every release since 7.0 and is fixed in 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 and 18.11.13. Those newer releases, not the October 12 ones, are what you should be targeting today.
What happened at Alpine
Condensed from Alpine's own timeline:
- October 13: The team upgrades GitLab, but installs 19.3.4 by mistake instead of 19.3.5, the release that contains the fix.
- October 20–21: A newly registered account starts submitting crafted CI configurations. GitLab workers crash eight times. In four of them, the attacker gets partway through the exploit before failing at the next step. The attacker also downloaded Alpine's GitLab container image, which suggests they were tuning the exploit for that specific build.
- October 22: GitLab is upgraded to 19.3.6, yet the server stays vulnerable. Alpine's image used stock Ruby rather than GitLab's patched Ruby, so the fix never applied.
- October 26–28: The gap is discovered. Access is restricted to developers and build servers, the instance is rebuilt from scratch, every password is reset and GitLab's secret keys are replaced.
Alpine's conclusion is worth noting. There is no evidence of code execution, but some logs from the day of the attack are missing and outbound connections were not recorded, so it cannot be ruled out. Had the attack worked, emails, password hashes, 2FA secrets, CI/CD variables, runner tokens, integration credentials and private repositories could all have been exposed.
What went right: the keys were never there
This may be the most useful part of the report. Alpine's package signing keys have never lived on the GitLab server. The team verified the relevant commits against a developer's local clone and against records from all 45 builders, confirming independently of GitLab that the packages and the October 21 releases were not tampered with.
A Linux distribution's GitLab is part of the pipeline that produces packages installed on a huge number of systems. Code execution there could have turned a single server compromise into a supply chain incident. Your company's GitLab plays the same role at a smaller scale: everything that reaches production passes through it, and your deploy credentials probably sit in its CI variables.
Lessons for developers and DevOps teams
1. A patch is more than the main package
If you run GitLab from source, from a distribution package or from your own image, upgrading GitLab alone does not close the hole. GitLab's October 21 advisory states plainly that if you use your own Ruby runtime, you also need Ruby 3.3.13, 3.4.12, 4.0.9 or later. Official Omnibus packages and images already include the patched Ruby.
# On an Omnibus install, show the GitLab and Ruby versions
sudo gitlab-rake gitlab:env:info
# If you bring your own Ruby
ruby -v2. Verify the version you actually installed
Alpine's first slip was a simple version mix-up. For critical fixes, copy the target version straight from the advisory and confirm after the upgrade that you are really running it. It takes five minutes.
3. Open sign-up and public projects are attack surface
The account that hit Alpine was brand new. An internal GitLab rarely needs open registration or the ability for anyone to create public projects. Review admin approval for sign-ups, allowed email domains and default project visibility.
4. No logs, no answers
Alpine could only say it cannot rule out a compromise because logs were missing. Its own takeaways include recording outbound connections and database connections from the GitLab host and keeping logs for longer than 14 days. GitLab has also published threat detections for self-managed instances, one of which targets Onigmo-related worker crashes. If you have seen unexplained worker crashes in recent weeks, take them seriously.
5. Design secrets to live outside the CI server
Keeping signing keys and the most sensitive credentials off the CI server is what spared Alpine the worst case. Prefer short-lived credentials where you can. If you patched late, consider rotating runner tokens, keys stored in CI variables and integration tokens.
Takeaway
Technically, CVE-2026-97229 is a bug in a regex engine. The bigger story is how valuable a self-hosted CI/CD server is as a target, and how a patch can consist of more moving parts than you expect. I suggest reading Alpine's report with your team as a tabletop exercise: if the same attack hit our GitLab, could we tell whether code was executed? If the honest answer is no, logging and secrets management should be next on the list right after patching.
Sources
- Alpine Linux: GitLab security incident (CVE-2026-97229)
- GitLab Critical Patch Release: 19.4.2, 19.3.4, 19.2.8
- GitLab Critical Patch Release: 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10, 18.11.13
- BleepingComputer: Over 1,000 GitLab servers vulnerable to ongoing RCE attacks
- BleepingComputer: Alpine Linux rebuilds GitLab after attempted RCE attack
- Help Net Security: GitLab admins urged to patch critical RCE flaw (CVE-2026-97229)