The critical vulnerability CVE-2026-97229 (CVSS 10.0) in the Onigmo regular expression engine embedded in Ruby was used to attack the GitLab server of the Alpine Linux project. According to Alpine Linux, on 20–21 October 2026 a newly registered account sent specially crafted CI configurations to the gitlab.alpinelinux.org server. The key issue: updating GitLab to version 19.3.6 did not eliminate the vulnerability, because the Alpine image used the system Ruby instead of the patched Ruby from the official GitLab packages. Administrators of self-compiled GitLab installations and custom container images need to update both GitLab and Ruby to versions 3.3.13, 3.4.12 or 4.0.9. The vulnerability was added to the CISA KEV catalog on 29 October 2026. We have already written about this vulnerability earlier.
Essence of the vulnerability
According to the CVE entry, CVE-2026-97229 is an integer overflow (CWE-190) in the Onigmo regular expression compiler that Ruby uses to process regex. GitLab compiles regular expressions from CI/CD configurations using Ruby, which allows an attacker to achieve remote code execution on the server via a specially crafted regular expression in the .gitlab-ci.yml file.
The vulnerability affects GitLab CE/EE versions:
- 19.2 up to 19.2.8
- 19.3 up to 19.3.5
- 19.4 up to 19.4.2
Rapid7 reproduced the full exploitation chain on the official GitLab 19.4.1 CE image, achieving command execution as the system user git. On the patched 19.4.2 image, the same input did not work. An important detail: in the Rapid7-tested attack path, the attacker first has to place a malicious CI configuration and a file with UTF-8 characters in its path in a public project — only the final CI lint request is unauthenticated. This requirement is removed on servers where new users can self-register and create projects.
Timeline of the attack on Alpine Linux
According to Alpine Linux, events unfolded as follows:
- 13 October — Alpine updated the server to GitLab 19.3.4 instead of 19.3.5 (an error during the update). The server remained without the fix released on 12 October.
- 20–21 October — a newly registered account sent specially crafted CI configurations, causing 8 crashes of GitLab worker processes. In 4 of them the attacker partially progressed along the exploitation chain, but did not complete the next step. The 21 October attack also triggered 502 errors and CI job failures.
- 22 October — Alpine updated the server to GitLab 19.3.6, but the vulnerability remained (the system Ruby was not updated).
- 23 October — the attacker’s account was blocked.
- 25–26 October — the attacker tried to regain access, but unsuccessfully.
- 26 October — Alpine discovered that the server was still vulnerable after the GitLab update.
- 27 October — the server was closed to everyone except developers and build servers.
- 28 October — the server was completely rebuilt from scratch with Ruby 3.3.13, all secret keys were replaced, and passwords for all accounts were reset.
Alpine also recorded that the attacker downloaded the project’s GitLab container image, which, in Alpine’s assessment, indicates preparation of an exploit tailored to that specific build.
Why updating GitLab didn’t help
This is the central lesson of the incident. The GitLab fix from 12 October included a patched Ruby inside the official Linux packages and GitLab container images. However, Alpine used its own image with the system Ruby, not the Ruby from the GitLab packages. Updating GitLab does not affect a separately installed Ruby — the vulnerable Onigmo regular expression compiler remains in place.
Thus, the boundary of the fix has two dimensions: the official GitLab packages contain the patched Ruby, while self-compiled installations and custom container images require a separate Ruby update. The fixed Ruby versions — 3.3.13, 3.4.12 and 4.0.9 — were released on 22–23 October. At the same time, as of 29 October, none of the GitLab advisories for self-compiled installations pointed out the need to update Ruby, and the source installation guide still listed Ruby 3.2 as the minimum version. Ruby 3.2 reached end of life in April 2026 and will not receive a fix — users on this branch must migrate to a supported version.
What was and wasn’t established
Alpine did not find any signs of attacker code execution: timing measurements did not show delays, and no foreign files, keys, hooks or processes were found. However, Alpine cannot rule out successful exploitation. As stated in the project’s report, a successful exploit leaves no crash and no traces in the web logs. Some logs for the days of the attack were lost, including background job logs and the file system from the old container. Neither Alpine nor its hosting provider collected logs of outgoing network connections.
The lack of outbound telemetry and incomplete logs are key factors that prevented clean forensics. This increases the importance of the six detection rules published by GitLab for self-managed instances, and of host-based checks.
If exploitation was successful, the following could have been compromised: users’ email addresses, names and IP addresses; password hashes; 2FA secrets; CI/CD variables and runner tokens; webhook, integration and mirroring credentials; personal access token hashes; private repositories and confidential issues. Alpine stresses that package and release signing keys were never stored on the GitLab server, and all changes to aports during the attack period were verified against external records.
Recommendations
For GitLab administrators
- Official Linux packages or GitLab container images: update to the latest release for your branch (19.4.2, 19.3.5, 19.2.8 or newer — the releases from 21 October also close a separate vulnerability, CVE-2026-110264).
- Self-compiled installations or images with your own Ruby: update both GitLab and Ruby to 3.3.13, 3.4.12 or 4.0.9. Ruby 3.2 will not receive a fix.
- Temporary measures (as recommended by Rapid7): restrict anonymous access to public projects, prevent untrusted users from creating public projects, and block the CI lint route. These steps cover only the Rapid7-tested exploitation path.
- Detection: use GitLab’s six detection rules in Sigma format. Check for files owned by the git user in /tmp, unexpected child processes of Puma or Sidekiq, outgoing connections, and modified crontab or SSH keys for the git user.
- If you detect signs of code execution, treat the server as compromised and rotate the secrets in gitlab-secrets.json, all CI/CD variables, runner tokens and access tokens.
For Alpine Linux users
- Users of the alpinelinux/gitlab image should re-pull the 19.3.6 tag — the image dated 27 October contains Ruby 3.3.13; earlier pulls are vulnerable.
- Ruby packages in Alpine have already been fixed: Ruby 3.4.12 on Alpine 3.22–3.24 and edge, Ruby 3.3.13 on Alpine 3.21. It is sufficient to run
apk upgrade. - Account owners on gitlab.alpinelinux.org will need to reset their password when the server reopens. If the same password was used on other sites, it should be changed there as well.
The Alpine Linux incident demonstrates a concrete and reproducible scenario: updating GitLab without updating Ruby leaves the server vulnerable to CVE-2026-97229. Administrators of self-compiled installations and custom GitLab container images must immediately check the Ruby version on their servers and update it to 3.3.13, 3.4.12 or 4.0.9 — updating GitLab alone does not close this vulnerability.












