CISA Adds a CVSS 10 GitLab Flaw to Its Exploited List, and Alpine Linux Found That Upgrading GitLab Does Not Fix It Without a Patched Ruby
CISA lists a CVSS 10 GitLab flaw as exploited with a November 1 deadline, and Alpine Linux says its upgrade did not close the hole because the bug is in Ruby’s regular expression engine and GitLab...
CISA added CVE-2026-97229, a CVSS 10.0 code-execution flaw in GitLab Community and Enterprise Edition, to its Known Exploited Vulnerabilities (KEV) catalog on Thursday, October 29, with a federal due date of Sunday, November 1. The only public account of an attack that we found is Alpine Linux’s incident report: its GitLab server was targeted on October 20 and 21, eight days after GitLab shipped its fix, and its own upgrade on October 22 did not close the hole. Alpine says the attack “came close to working,” that it has “found no evidence that it succeeded,” and that it cannot rule success out, so it rebuilt the server from scratch.
Table Of Content
The upgrade failed because the bug is not in GitLab’s code. It is in Onigmo, the regular expression engine inside Ruby, and GitLab fixes it by patching the Ruby that ships in its own packages and container images. Alpine’s image used stock Ruby. Upstream Ruby released its fixes on October 22 and 23, ten and eleven days after GitLab’s October 12 patch release, and the Ruby project says it has not requested CVE identifiers for them, so a scanner has to track GitLab’s four. This is the sixth GitLab entry in KEV and the second added within 48 days (our count from the feed): we covered the September 11 one. Below we set out the timeline, which versions fix what, where the accounts differ, and what we could not check.
What happened, in order
Times are UTC. Pull-request and release times come from GitHub’s API, advisory dates from GitLab’s release notes, the attack account from Alpine’s post, and CVE dates from the CVE.org records. Weekdays and day counts are our arithmetic.
| When | What happened | Source |
|---|---|---|
| May 16, 2025 (Fri) | Ruby merges change #13332, the double-free fix. It first ships in Ruby 4.0.0 on December 25, 2025, and in the 3.3 and 3.4 lines only on October 23, 2026, 525 days after the merge. | GitHub API, Ruby advisory |
| Apr 29, 2026 (Wed) | Ruby merges change #16801, the fix for overflowed internal IDs in patterns with many repeats. It first ships on October 23, 177 days later. | GitHub API, Ruby advisory |
| Sept 23 (Wed) | The first of three critical patch releases for these bugs, 19.4.1, 19.3.3 and 19.2.7, fixes CVE-2026-89078 and CVE-2026-93577 (CVSS 9.9, authenticated). | GitLab release notes |
| Sept 24 to 25 | GitLab, as the CVE numbering authority, reserves CVE-2026-97229 on Sept 24 at 10:04. On Sept 25 at 04:29 Ruby merges change #19020, the program-size overflow fix. | CVE.org, GitHub API |
| Oct 12 (Mon) | GitLab releases 19.4.2, 19.3.5 and 19.2.8 for CVE-2026-97229 (CVSS 10.0). Its notes list the Ruby patches among the bug fixes, for example “Add Ruby regexp program size patch for 3.3 and 3.4 [19.4].” | GitLab release notes |
| Oct 13 (Tue) | CVE-2026-97229 is published. Rapid7 publishes its write-up, says it “independently reproduced arbitrary code execution on an unpatched, official GitLab CE image,” and notes that it added a link to its proof-of-concept repository. Alpine upgrades its server to 19.3.4 instead of 19.3.5 “by mistake.” GitLab reserves CVE-2026-110264 at 18:34. | CVE.org, Rapid7, Alpine |
| Oct 20 to 21 (Tue to Wed) | A newly registered account sends crafted CI configurations to Alpine’s server. GitLab worker processes crash 8 times; in 4 of the crashes the attacker gets partway through the exploit and fails at the next step. The attacker also downloads Alpine’s GitLab container image. | Alpine |
| Oct 21 (Wed) | GitLab releases 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 and 18.11.13 for CVE-2026-110264 (CVSS 10.0), which affects all versions from 7.0. | GitLab release notes, NVD |
| Oct 22 (Thu) | The GitHub release for Ruby 4.0.8, which carries the program-size fix, is stamped 07:08. Alpine upgrades its server to GitLab 19.3.6, which does not fix the problem for its image. CVE-2026-110264 is published. | GitHub API, Alpine, CVE.org |
| Oct 23 (Fri) | Ruby publishes its advisory at 03:11, tying GitLab’s four CVEs to three Ruby changes. The GitHub releases for Ruby 3.4.12, 4.0.9 and 3.3.13 are stamped between 04:00 and 04:28. | Ruby advisory, GitHub API |
| Oct 25 to 28 | The attacker returns and tries to get back in; the attempts fail. Alpine finds on Oct 26 that its instance is still vulnerable, closes GitLab on Oct 27 and starts a rebuild. Docker Hub shows the alpinelinux/gitlab:19.3.6 tag last pushed at 06:12 on Oct 27, and Alpine says the image published that day contains Ruby 3.3.13. Alpine publishes its incident post on Oct 28. | Alpine, Docker Hub |
| Oct 29 (Thu) | CISA adds CVE-2026-97229 to KEV (feed released 19:09), with a due date of November 1, ransomware use “Unknown” and forensic triage marked yes. Alpine’s timeline lists GitLab as reopened on 19.3.7. | CISA KEV feed, Alpine |
| Oct 30 (Fri) | SecurityWeek reports the Alpine attack and the KEV listing. Alpine’s “GitLab is back” post carries this date. | SecurityWeek, Alpine |
Alpine says its packages and releases were not altered. It writes that “the aports repository, packages, and the October 21 releases were not tampered with,” and that the keys that sign its packages and releases “are not, and never have been, stored on the GitLab server.” Its checks covered commits from October 20 to 22 and packages built through October 24, and it said it was extending them to October 27, the day it closed GitLab.
Why upgrading GitLab did not fix it
Ruby’s advisory of October 23 says its new releases fix “several bugs in Ruby’s regular expression engine (Onigmo) that GitLab found could be used for remote code execution on GitLab servers,” and that “GitLab addressed these issues in its own releases by patching the Ruby it ships.” GitLab’s release notes show the mechanism: the 19.4.2 notes list “Add Ruby regexp program size patch for 3.3 and 3.4 [19.4]” and “Add Ruby regexp repeat-range double-free patch for 3.3 and 3.4 [19.4]” as bug fixes, and the 19.5.1 notes list “Add Ruby regexp repeat ID overflow patch for 3.3, 3.4 and 4.0.” Alpine states the consequence: “The fix isn’t in GitLab’s own code but in a patch to Ruby, which GitLab applies only in its official packages. Our image used standard Ruby, so it didn’t get the patch.”
| CVE | GitLab’s description | Account needed (CVSS 3.1) | GitLab fix | Ruby change and first release with it (3.3 / 3.4 / 4.0) |
|---|---|---|---|---|
| CVE-2026-89078 | Double free when parsing a pattern in CI/CD configuration | Authenticated, 9.9 | Sept 23: 19.4.1, 19.3.3, 19.2.7 | #13332: 3.3.13 / 3.4.12 / 4.0.0 |
| CVE-2026-93577 | Integer overflow when compiling a pattern in CI/CD configuration | Authenticated, 9.9 | Sept 23: same releases | #19020: 3.3.13 / 3.4.12 / 4.0.8 |
| CVE-2026-97229 | Integer overflow in the CI/CD regular expression compiler | No privileges, 10.0 | Oct 12: 19.4.2, 19.3.5, 19.2.8 | #19020: 3.3.13 / 3.4.12 / 4.0.8 |
| CVE-2026-110264 | Integer overflow when compiling a pattern | No privileges, 10.0 | Oct 21: 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10, 18.11.13 | #16801: 3.3.13 / 3.4.12 / 4.0.9 |
The first three CVEs affect GitLab from 19.2; CVE-2026-110264 affects all versions from 7.0. The pairing of CVEs to Ruby changes is Ruby’s, from its advisory table, and GitLab credits one reporter, joaxcar, on all four through its HackerOne program.
The table also shows what an administrator on stock Ruby faced. For the 3.3 and 3.4 lines, the ones GitLab patched, no stock release carried any of the three fixes until October 23, three days after Alpine’s server was first probed. Ruby 4.0 had the double-free fix from its first release, but its other two fixes shipped in 4.0.8 on October 22 and 4.0.9 on October 23. Two of the three changes had sat in Ruby’s main branch for months: #13332 for 525 days before it reached the 3.x lines and #16801 for 177 days before any release. We cannot tell from public records why they were not released earlier. The same gap between a merged fix and a release is the shape we described for the Brotli flaw. Ruby’s own explanation of its stance is that it “has generally considered it unsafe to compile and use a regular expression created from untrusted input,” and that its documentation “discusses untrusted patterns only in terms of denial of service.”
Ruby did not limit the problem to GitLab. The advisory says the bugs are reached “only when an application compiles a regular expression from a string that an attacker controls,” for example through Regexp.new, Regexp.union or Regexp.compile, and that “Applications that only use regular expressions written by their own developers are not affected.” It says a regexp timeout does not protect against them, and that “Limiting the length of patterns does not reliably protect against them either, because some of them can be triggered by short patterns.” CISA’s KEV entry makes the same point: “Other products can potentially be affected by the same underlying Ruby/Onigmo Integer Overflow issue in CI/CD Regular Expression Compiler.”
Ruby 3.3 is in security maintenance, and the project says 3.3.13 “includes these fixes as an exception, because GitLab assigned CVEs to issues that rely on them.” Ruby’s branches page lists 3.2 as end of life since April 1, 2026, and the advisory names no fix for it or anything older. Ruby also says: “We have not requested CVE identifiers in Ruby for these fixes, at least for now,” and asks users to “please refer to GitLab’s CVE identifiers listed above when you track these issues, for example in a security scanner.” A scanner that matches Ruby versions against Ruby CVEs therefore has no record to match; that consequence is our reading, not Ruby’s statement.
Who can reach it
The vendor’s CVSS vector for CVE-2026-97229 and CVE-2026-110264 requires no privileges, and SecurityWeek’s summary says the bug “allows unauthenticated attackers to execute arbitrary code on the server.” Rapid7, which reproduced the chain, adds a condition: “an attacker must have a mechanism to plant a malicious CI/CD configuration to a repository prior to triggering the vulnerability,” and “On GitLab instances where new users can self register and create projects, this constraint is removed.” Alpine’s attacker used a newly registered account, which fits. GitLab’s documentation says “By default, any user visiting your GitLab domain can create an account,” lists administrator approval of new accounts as a separate restriction (“enabled by default for new GitLab instances”), and Alpine now requires an admin to approve new password-based accounts. Rapid7 suggests restricting anonymous access to public projects and keeping untrusted users from creating or writing to public projects, and says these controls “address only the demonstrated delivery path and do not remediate the vulnerable regular expression compiler.”
GitLab says it released six threat detections for self-managed instances for CVE-2026-97229 (among them “Onigmo native worker crash” and “ci lint workhorse worker crash”) and two for CVE-2026-110264; the full lists are in its advisories. For exposure, Censys’s advisory, dated October 13, counted 25,766 of the 82,454 GitLab hosts it detects (about 31 percent, our arithmetic) on a version in the October 12 affected range. A version-based count cannot see Alpine’s situation, a fixed GitLab version running unpatched stock Ruby, so we read it as a floor, not a total. FIRST’s EPSS, a probability model and not an observation, gave CVE-2026-97229 a score of 0.184 (97th percentile) on October 29, against 0.013 for CVE-2026-110264 and 0.006 and 0.005 for the two September CVEs.
Where the accounts differ
- “Failed.” SecurityWeek’s lead says the flaw “was exploited one week after disclosure in a failed attack against Alpine Linux’s instance.” Alpine says it has “found no evidence that the attacker ran code on the server, but we cannot rule it out,” that some logs from the attack day are gone, and that it had no logging of outbound connections. It treated the server as compromised. We use Alpine’s wording: an attempt whose outcome is unknown.
- “Unauthenticated.” That is the vendor’s scoring for two CVEs. Rapid7’s account needs the ability to plant a CI configuration, and Alpine’s attacker registered an account first. GitLab itself labels the two September CVEs authenticated.
- Which CVEs count as exploited. CISA’s KEV feed (catalog 2026.10.29) lists CVE-2026-97229 only. CVE-2026-89078, CVE-2026-93577 and CVE-2026-110264 are not in it. In the CVE records, CISA’s SSVC entry reads exploitation active for CVE-2026-97229, and the CVE-2026-110264 record, last updated October 22, reads none.
- Whose patch. GitLab’s and Ruby’s pages describe Ruby patches inside GitLab’s releases, and Alpine adds that GitLab applies them “only in its official packages.” We found no statement in GitLab’s, Ruby’s or Alpine’s pages on whether GitLab’s patched Ruby changes its reported version string, so we do not suggest judging a GitLab package by that string.
- Reopening. Alpine’s timeline lists the server as reopened on October 29, while its “GitLab is back” post is dated October 30. Docker Hub shows the 19.3.7 image pushed on October 29 at 18:42.
What to check now
- Upgrade GitLab to the October 21 releases or later: 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 or 18.11.13 for the branch you run. The October 12 releases cover CVE-2026-97229 but not CVE-2026-110264, whose affected range includes 19.4 before 19.4.3, 19.3 before 19.3.6 and 19.2 before 19.2.9. GitLab.com is patched, and GitLab says Dedicated tenants on its recent internal releases need no action.
- If you run your own Ruby, from source or in your own image, Alpine’s warning applies: “upgrading GitLab is not enough: you also need Ruby 3.3.13, 3.4.12, 4.0.9 or later.” Ruby 3.2 and older are end of life and the advisory names no fix for them, so the move is to a supported line.
- If you use Alpine’s image, Alpine says to pull
alpinelinux/gitlab:19.3.6again: the image published on October 27 contains Ruby 3.3.13, and any 19.3.6 image pulled earlier and all older tags are vulnerable. - Narrow who can plant a CI configuration. Use GitLab’s sign-up restrictions (disable sign-up or require administrator approval) and limit who can create public projects. Treat that as exposure reduction, per Rapid7, and not a fix.
- Look for what Alpine saw. Alpine’s signs were a new account, crafted CI configurations, worker crashes, 502 errors and failed CI jobs, and GitLab’s detections are in its advisories. Alpine also warns that “A successful exploit would leave no crash and no trace in the web logs,” so quiet logs prove little.
- Treat past exposure as possible compromise. CISA marks the entry for forensic triage, which, as we explained in our PAN-OS report, means federal agencies must check whether a system was compromised before patching it. Alpine rebuilt from scratch, replaced GitLab’s secret keys (so passwords, 2FA and tokens stopped working) and emptied every CI/CD variable value. Alpine’s list of what a successful attacker could have reached covers user emails and IP addresses, password hashes, 2FA secrets, CI/CD variables, runner tokens, webhook and integration credentials, and private repositories. Our inference, not CISA or GitLab guidance: an instance that untrusted users could reach while it ran an unpatched Ruby at any point after October 13, the day Rapid7 published, is a candidate for the same rebuild and rotation.
- Look beyond GitLab. Alpine says “any program that compiles regular expressions from untrusted input is exposed, not only GitLab,” and that its Ruby packages are fixed (3.4.12 on Alpine 3.22, 3.23, 3.24 and edge; 3.3.13 on 3.21), so it says “Run apk upgrade to get it.”
- Federal agencies have until Sunday, November 1 under CISA’s three-day BOD 26-04 deadline for this entry.
What is still unknown
- Whether Alpine’s attempt succeeded. Alpine cannot rule it out, and it lacks some attack-day logs and any outbound connection logs.
- Whether anyone else was hit. The KEV entry names no victim and gives no evidence, and we found no other public victim account.
- Who the attacker is. We found no attribution.
- Whether Ruby will request CVE identifiers. Its advisory says it plans to discuss that and will update the page if it does.
- How many stock-Ruby installs run a fixed GitLab version. No public count exists, and version-based scans would not see them.
- What GitLab’s tracker says. NVD’s links to GitLab’s issues and the HackerOne reports are tagged “Permissions Required,” and GitLab says it makes issue details public 90 days after the release that fixed them.
Sources and method
We read Alpine’s incident post and its “GitLab is back” post, GitLab’s release notes for 19.4.1, 19.4.2 and 19.5.1, Ruby’s advisory and branches page, SecurityWeek’s article, Rapid7’s write-up, Censys’s advisory and GitLab’s sign-up restrictions page. We checked the records directly: the NVD entries for all four CVEs (the entry for CVE-2026-97229 was still “Undergoing Analysis” at 10:15 UTC today), the CVE.org records for CVE-2026-97229 and CVE-2026-110264, CISA’s KEV feed (checked at 10:15 UTC), FIRST’s EPSS API, GitHub’s API for Ruby’s three pull requests and releases (the post gives only their numbers, merge times and release times, and leaves out their technical descriptions), and Docker Hub’s tag list for Alpine’s image, which matches Alpine’s dates (19.3.4 pushed October 13 at 11:25, no 19.3.5 tag, 19.3.6 last pushed October 27 at 06:12, 19.3.7 pushed October 29 at 18:42). The day counts, the 31 percent share and the count of GitLab entries in KEV are our arithmetic from those records. We did not read, run or link exploit code, we did not open Rapid7’s proof-of-concept repository, and we have not tested anything against a GitLab or Ruby build. Every claim about what happened on Alpine’s server rests on Alpine’s own account.








No Comment! Be the first one.