Alpine Linux says a GitLab CVE-2026-97229 attack came close: no tampering found, code execution not ruled out
Alpine Linux says an attacker tried GitLab CVE-2026-97229 on its server on 20 and 21 October, crashing workers 8 times, and that its checks found no tampering with packages. It cannot rule out code execution, and upgrading GitLab did not fix the flaw because the fix lives in Ruby.
By Parminder Kumar Sharma · LinkedIn · · 16 min read
Eight worker crashes, four of them partway, and an instance Alpine could not clear
Alpine Linux says an attacker sent crafted CI configurations to its GitLab server on 20 and 21 October 2026 and crashed GitLab worker processes 8 times. In 4 of those crashes, Alpine says, the attacker "got partway through the exploit and failed at the next step" (derived: the other 4 are not described). The instance still ran GitLab 19.3.4, so the first of those days was 8 days after GitLab's fix of 12 October and the second was 9 days after it (derived). Alpine's account, read in full at 09:49 UTC on 30 October 2026, is its post of 28 October, updated 30 October.
What that does not establish is whether any code ran. Alpine's wording is: "We have found no evidence that it succeeded, but we cannot rule it out, so we treated the instance as compromised and rebuilt it from scratch." It gives three reasons for the doubt: a successful exploit would leave no crash and no trace in the web logs, some logs from the attack day are gone, and there was no logging of outbound network connections, at Alpine or at its hosting provider.
The press summary is firmer than the primary. SecurityWeek wrote on 30 October that "The attack failed" (its wording). Alpine's own post says the attack "came close to working" and that it has no evidence of success. Those are not the same claim: "failed" is a reading, and "not shown to have succeeded" is what the record supports. Nor does CISA's catalogue entry of 29 October for CVE-2026-97229 name Alpine: it names no victim and does not say what evidence it rests on, and its analysis is in the earlier briefing on the KEV listing, which this one does not repeat.
Alpine is both the victim and the only source for what happened, and it has an interest in showing that its packages are sound. GitLab sells the product and wrote the advisory and detections used below. Read each side with that in mind; where a claim is Alpine's, it is attributed as Alpine's.
What Alpine's post states and what it does not. Source: Alpine Linux, post of 28 October 2026 updated 30 October, read 30 October 2026.
| Question | Stated by Alpine | Not stated |
|---|---|---|
| Which bug | The post is titled "attempted exploitation of CVE-2026-97229" and calls CVE-2026-97229 a critical flaw in how GitLab evaluates regular expressions in CI configuration. | The crafted CI configurations, the account name, source addresses or log lines that tie the crashes to this CVE. None is printed. |
| Did code run | No evidence it did. Timing probes showed no delays; no unexpected files, keys, hooks or processes were found. It cannot rule it out. | A positive finding either way. Alpine says the evidence it would need no longer exists. |
| What data left | No private data was returned to the attacker through any web or API request it can see. | Anything about data reached by code execution, if code ran. |
| Packages and releases | Source commits of 20 to 22 October and every package built from 20 to 24 October matched records outside GitLab. The four 21 October releases came from those commits. | Checks for 25 to 27 October. Alpine says it is extending the same checks to 27 October. |
| Signing keys | The keys that sign packages and releases are not, and never have been, stored on the GitLab server. | Where signing happens instead. |
| The attacker | A newly registered account sent the configurations, the attacker downloaded the GitLab container image, and returned on 25 and 26 October without success. | Who, from where, why, or what the return attempts were. |
The timeline, as Alpine prints it
Alpine's post carries its own incident timeline, reproduced below as a screenshot, and the diagram under it adds GitLab's and Ruby's release dates. The dates give some gaps that Alpine does not state. From GitLab's fix on 12 October to Alpine closing the server on 27 October is 15 days (derived). The instance sat on 19.3.4 from 13 October to 22 October, 9 days (derived). From the main attack on 21 October to the closure is 6 days (derived), and Alpine's post appeared 7 days after that attack (derived). The upstream Ruby fix arrived on 23 October, 11 days after GitLab's own patched Ruby shipped on 12 October (derived).
Two details in the timeline carry weight. On 26 October Alpine "found the instance still vulnerable after the upgrade", which is 5 days after the main attack and 4 days after the upgrade it expected to fix things (derived). And on 25 and 26 October the attacker "returns and tries to get back in; attempts fail" after the account was blocked on 23 October. Alpine does not say how it knew the attempts failed or what they were.
The upgrade that did not fix it: the flaw lives in Ruby
Alpine's timeline has two version slips. On 13 October it upgraded to GitLab 19.3.4 "instead of 19.3.5 (which had the fix) by mistake". On 22 October, the day after the main attack, it upgraded to 19.3.6, and Alpine says that "didn't fix the vulnerability" either. Its explanation: "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."
GitLab's advisory of 12 October describes the flaw as insufficient regular expression validation in CI/CD configuration. In the saved copy, the word Ruby appears only in the bug fix lines, such as "Add Ruby regexp program size patch for 3.3 and 3.4 [19.3]", and no sentence tells an installation from source or a self built container image to upgrade Ruby. Ruby's own post of 23 October says the bugs are in Onigmo, Ruby's regular expression engine, and lists Ruby 4.0.9, 3.4.12 and 3.3.13 as the releases that contain the fixes. CISA's catalogue entry carries the same warning in its notes: "Other products can potentially be affected by the same underlying Ruby/Onigmo Integer Overflow issue in CI/CD Regular Expression Compiler."
The same gap applies to GitLab's second CVSS 10.0 regular expression flaw. Ruby's table lists CVE-2026-110264 as fixed in the same Ruby releases, and GitLab's 21 October notice carries a Ruby "repeat ID overflow" patch line under 19.3.6, which Ruby's table ties to "overflow of internal IDs in a pattern with many repeats" (a reading across two pages). Alpine's post does not mention CVE-2026-110264. On this site's reading (derived), an image on standard Ruby from before 27 October would have lacked that fix as well. The listing and the second flaw are covered in the earlier KEV briefing; GitLab's original wording is in the briefing on the advisory.
The press reading against the record
Coverage on 30 October compressed a careful post into a headline about exploitation. The table sets the SecurityWeek text against the Alpine post it links to. A second outlet's article, The Hacker News, could not be read: its page answered with a bot check, which was not bypassed.
SecurityWeek, 30 October 2026 (secondary), set against Alpine Linux's post (primary). Both read 30 October 2026.
| Coverage says | Alpine's post says | Reading |
|---|---|---|
| Exploited one week after disclosure in a failed attack. | Attempted exploitation, 20 and 21 October, "a week after the fix was released"; the attack "came close to working"; no evidence it succeeded, cannot rule it out. | 12 to 20 October is 8 days (derived). "Failed" is firmer than Alpine. |
| The attacker crashed the worker process. | Worker processes crashed 8 times; in 4 the attacker got partway and failed at the next step. | Matches, with the counts. |
| The vulnerability was not patched after updating to 19.3.6. | Upgrading to 19.3.6 on 22 October did not fix it because the image used standard Ruby. | Matches. The cause is the Ruby, not GitLab's code. |
| Alpine is still testing the instance before public release. | The 30 October update says GitLab is open again, on a new server running GitLab 19.3.7 with Ruby 3.3.13. | Overtaken by Alpine's own update. |
| Aports, packages and the 21 October releases were not tampered with. | "Our checks show" that, with the checks described and extended to 27 October. | Coverage drops the limits on the checks. |
Is it this CVE? What the record can and cannot tie together
Alpine names CVE-2026-97229 in the title of its post. The evidence it gives is a pattern: crafted CI configurations from a new account, 8 worker crashes, 4 of them partway, a container image download that Alpine reads as the attacker "tuning the exploit to our exact build". That is Alpine's inference from logs it does not print. GitLab's advisories list a detection called "Onigmo native worker crash" under both CVE-2026-97229 (six detections) and CVE-2026-110264 (two). So a worker crash alone does not separate the two flaws (derived). Alpine's attribution stands as Alpine's, and the record read does not let an outsider check it.
Two smaller points. First, Alpine's attacker used a newly registered account, while GitLab, in the CVE record, describes a flaw an unauthenticated user could reach. The record does not establish whether the account was needed. After the rebuild, Alpine says new accounts registered with an email address and password "must now be approved by an admin".
Second, the CVE record itself changed. The copy read on the evening of 29 October carried a CISA SSVC entry stamped 2026-10-29T19:50:05.704572Z. The copy read on 30 October carries the same fields stamped 2026-10-13T00:00:00+00:00, and the record's last update is 2026-10-30T03:55:54.495Z. The record gives no reason. A stamp of 13 October does not establish exploitation on 13 October: the earliest attempt Alpine describes is 20 October, and CISA's catalogue entry was added on 29 October.
CISA ADP SSVC entry in the CVE record for CVE-2026-97229, as read twice. CVE Program record (GitLab as CNA), saved at both reads.
| Read | SSVC timestamp | Record dateUpdated | Exploitation, Automatable, Technical Impact |
|---|---|---|---|
| 29 October 2026, evening | 2026-10-29T19:50:05.704572Z | 2026-10-29T19:58:23.528Z (CISA ADP container) | active, yes, total |
| 30 October 2026, morning | 2026-10-13T00:00:00+00:00 | 2026-10-30T03:55:54.495Z | active, yes, total |
What Alpine checked, and the three days it did not
Alpine's integrity claim rests on comparing its source commits and packages with records the attacker could not reach. It says every commit added to aports from 20 to 22 October "arrived through a recorded push by a known developer", checked against a developer's clone and all 45 builders. It says every package built from 20 to 24 October, on every architecture, came from commits as published, and that the four 21 October stable releases, including their ISO images and minirootfs tarballs, came from those same verified commits.
The limit is in Alpine's next sentence: the checks ran on 24 October, covering commits from 20 to 22 October and packages built up to 24 October, while the GitLab instance "stayed vulnerable until we closed it on October 27". That leaves a window of 3 days (derived) that Alpine says it is extending the checks to cover. Neither post read says the extension is finished.
Alpine also prints what could have been exposed if the attack had succeeded: email addresses, names and IP addresses of all users; password hashes; 2FA secrets, CI/CD variables and runner tokens; webhook, integration and push mirror credentials; personal access tokens (stored as hashes); and private repositories with confidential issues and merge requests. Alpine says it replaced GitLab's secret keys, reset all passwords and 2FA, and emptied every CI/CD variable value, advising maintainers to "assume the old values may have been exposed".
It also reports a separate thing: "automated login attempts against our GitLab with passwords leaked from other sites". Alpine does not link those attempts to the CVE, and neither does this briefing.
Technical details
Neither Alpine nor GitLab prints indicators for this attack: no addresses, account names, hashes, crafted CI configuration text, requests or log lines. This site prints none, and no exploit. What the primaries do print is below, copied as published and attributed. Anything this site derived is marked.
GitLab says it released six threat detections for self managed instances against CVE-2026-97229. The advisory prints their names only, not rule bodies. A defender can look for those events in whatever GitLab security tooling is in use, over the window from 12 October. The names are exactly as printed.
Onigmo native worker crash
Graphql cilint hostile regexp
ci regexp oversized non ascii path
ci regexp guard rejection
ci lint workhorse worker crash
ci lint scripted client error burst
For CVE-2026-110264, GitLab's 21 October notice lists two detections. The first has the same name as one above, which is why a worker crash alone does not tell the two flaws apart (derived).
Onigmo native worker crash
Org mode render error burst
The CVE record, published by GitLab as the numbering authority, gives the affected and fixed GitLab versions and the vector. A defender compares the GitLab version in use, and then separately the Ruby.
all versions from 19.2 before 19.2.8, 19.3 before 19.3.5, and 19.4 before 19.4.2
Upgrade to versions 19.2.8, 19.3.5, 19.4.2 or above.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Ruby's post prints which Ruby change fixes the bug behind each GitLab CVE. This is the table that settles the Ruby version question; the first Ruby release in each series that contains the fix is shown.
Ruby's table of fixes behind the GitLab CVEs. Ruby project news post of 23 October 2026, read 30 October 2026.
| GitLab CVE | Bug in Ruby, as printed | Ruby 4.0 | Ruby 3.4 | Ruby 3.3 |
|---|---|---|---|---|
| CVE-2026-89078 | Double free when parsing a pattern fails after an alternation | 4.0.0 | 3.4.12 | 3.3.13 |
| CVE-2026-93577, CVE-2026-97229 | Integer overflow in the size of a compiled pattern | 4.0.8 | 3.4.12 | 3.3.13 |
| CVE-2026-110264 | Overflow of internal IDs in a pattern with many repeats | 4.0.9 | 3.4.12 | 3.3.13 |
Ruby also says when an application is exposed: only when it compiles a regular expression from a string an attacker controls, and that "Regexp.timeout does not protect" and a pattern length limit does not reliably protect either. Its stated workaround if upgrading is impossible is to avoid compiling regular expressions from untrusted input.
Alpine's own remediation text is below, copied from its two posts. The first block is for anyone running Alpine's GitLab container image or Alpine's Ruby package. Alpine's reopening post also tells users of gitlab.alpinelinux.org to remove the old SSH host key and check the new one; the three fingerprints are on Alpine's page and are deliberately not reproduced here, so that the check is made against Alpine's own page.
If you use our alpinelinux/gitlab container image, pull alpinelinux/gitlab:19.3.6 again. The image published on October 27 contains Ruby 3.3.13. Any 19.3.6 image you pulled before October 27, and all older tags, are vulnerable.
Alpine 3.22, 3.23, 3.24 and edge ship Ruby 3.4.12, and Alpine 3.21 ships Ruby 3.3.13; both include the fix. Run apk upgrade to get it.
ssh-keygen -R gitlab.alpinelinux.org
Finally, the two release facts that Alpine's integrity statement refers to, as its 21 October announcement prints them.
3.21.9
3.22.7
3.23.7
3.24.3
What to do, in the order worth doing
Take this with you
Defender checklist for anyone running GitLab
- List every GitLab you run and how each one gets its Ruby: GitLab's official package or image, an install from source, or your own container image. The version on the dashboard only answers half of that.
- For anything not on GitLab's official packages, confirm the Ruby is 3.3.13, 3.4.12, 4.0.9 or later, as Alpine and Ruby both say. If it is not, treat the instance as vulnerable whatever its GitLab version.
- Before you patch or rebuild, preserve evidence: copy the GitLab logs, the background job logs and the container filesystem, because Alpine lost some and had no outbound connection logs. Then search from 12 October for the detections GitLab lists, especially worker crashes.
- If you see worker crashes, 502 errors and failed CI jobs together with a recently registered account, take Alpine's route: treat the instance as compromised and rebuild it, as Alpine did, rather than patching in place.
- Rotate what the instance held, in the order Alpine lists: GitLab's secret keys, passwords and 2FA, CI/CD variable values, runner tokens, webhook, integration and push mirror credentials, and personal access tokens.
- Close the door on easy accounts: Alpine now requires admin approval for new registrations. Whether registration was needed for this flaw is not established, so this is hardening, not a mitigation.
- If you build or ship software from a GitLab you cannot vouch for, verify your own artefacts against records outside GitLab, as Alpine did with a developer's clone and its builders, and keep signing keys off the GitLab host.
- Downstream users of Alpine: run apk upgrade to pick up the fixed Ruby, and if you use the alpinelinux/gitlab image, pull the tag again; anything pulled before 27 October is vulnerable, per Alpine.
- Add outbound connection logging for the GitLab host and keep logs longer than 14 days, as Alpine says it is now doing, and set a rule to apply critical GitLab releases within a day and to read each release for Ruby or other component patches.
The question the version number hides
Alpine did much of what a defender is told to do. It upgraded, it noticed that the upgrade had not worked, it rebuilt, it checked its source against outside records, and it published the limits of what it knows. What failed was a label: the version said fixed while the Ruby said otherwise. GitLab's advisory, as saved, does not tell installs from source or from a self built image to upgrade Ruby; Ruby's post does.
When your change record says the GitLab upgrade is done, can you show which Ruby is compiling the regular expressions that users send to it, and would you learn that it was wrong from a log or from a headline?
Key facts
Sources
- PrimaryAlpine's post 'GitLab security incident: attempted exploitation of CVE-2026-97229', dated 28 October 2026 and updated 30 October: the timeline, what was found, what cannot be ruled out, the integrity checks, the exposure list and the remediation text. The primary, read in fullAlpine Linux Development Teamaccessed 2026-10-30
- PrimaryAlpine's post 'GitLab is back: what you need to do', 30 October 2026: the reopening on GitLab 19.3.7 with Ruby 3.3.13, the resets and the admin approval of new accounts. Read in fullAlpine Linux Development Teamaccessed 2026-10-30
- PrimaryAlpine's announcement of the 21 October stable releases 3.21.9, 3.22.7, 3.23.7 and 3.24.3, the releases it says were not tampered with. ReadAlpine Linux Development Teamaccessed 2026-10-30
- PrimaryAlpine news feed: the dates of the two incident posts and the release post. ReadAlpine Linux Development Teamaccessed 2026-10-30
- PrimaryGitLab Critical Patch Release 19.4.2, 19.3.5, 19.2.8, dated 12 October 2026: the CVE-2026-97229 entry, versions, CVSS vector, six detections, the Ruby patch lines and the 19.3.4 bug. The vendor's own advisory, read in fullGitLabaccessed 2026-10-30
- PrimaryGitLab Critical Patch Release 19.5.1, 19.3.6 and others, dated 21 October 2026: CVE-2026-110264, its two detections and the Ruby repeat ID overflow patch lines. ReadGitLabaccessed 2026-10-30
- PrimaryGitLab Patch Release 19.5.3, 19.3.7 and others, 29 October 2026: confirms that 19.3.7 exists, the version Alpine reopened on. ReadGitLabaccessed 2026-10-30
- PrimaryRuby news post of 23 October 2026: the four GitLab CVEs, Ruby 4.0.9, 3.4.12 and 3.3.13, the table of fixes, who is affected and the statement that Regexp.timeout does not protect. Read in fullRuby projectaccessed 2026-10-30
- PrimaryCVE record for CVE-2026-97229: description, versions, solution, vector, and CISA's ADP entry with its changed SSVC timestamp, read twice. Read in fullCVE Program (GitLab as CNA)accessed 2026-10-30
- PrimaryKnown Exploited Vulnerabilities file, catalogue version 2026.10.29: the entry for CVE-2026-97229, its notes about other products using the same Ruby code, and the absence of any victim. ReadCISAaccessed 2026-10-30
- Reported bySecurityWeek, 30 October 2026, 'Max-Severity GitLab Vulnerability Exploited Against Alpine Linux': the press reading set against Alpine's post. SecondarySecurityWeekaccessed 2026-10-30


