Detect GitLab CE/EE Unauthenticated RCE via Crafted CI/CD Regular Expression (CVE-2026-97229) in Microsoft Sentinel
Detects exploitation of CVE-2026-97229, an integer overflow or wraparound flaw (CWE-190) in GitLab CE/EE 19.2 before 19.2.8, 19.3 before 19.3.5 and 19.4 before 19.4.2 where insufficient regular expression validation lets an unauthenticated user run arbitrary code on the GitLab server through a specially crafted regular expression in a CI/CD configuration. The CVE is on the CISA KEV catalog (added 2026-10-29) and a Metasploit module exists. Detection focuses on what a GitLab host and its log pipeline can show: CI/CD configuration or pipeline requests carrying unusually long or nested regular expressions from unauthenticated sources, the GitLab Rails or Puma worker spawning shells or download tools, and new files or outbound connections from the GitLab service account shortly after such requests.
MITRE ATT&CK
- Tactic
- Initial Access Execution
KQL Detection Query
// df00tech DF00-142016b516 · https://df00tech.com/detections/CVE-2026-97229 · licence: https://df00tech.com/detections/licence
let lookback = 24h;
Syslog
| where TimeGenerated >= ago(lookback)
| where ProcessName in~ ("puma", "sidekiq", "gitlab-rails", "ruby")
| where SyslogMessage has_any ("/bin/sh", "/bin/bash", "curl ", "wget ", "nc ", "python")
| summarize Events = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Sample = take_any(SyslogMessage) by Computer, ProcessName
| order by LastSeen desc Flags GitLab host syslog where the Rails, Puma or Sidekiq worker processes launch shells or download tools, the observable footprint of code execution through CVE-2026-97229.
Data Sources
Required Tables
False Positives & Tuning
- Administrators running console or maintenance scripts through the Rails runner
- CI jobs on shared runners installed on the GitLab host
- Backup and upgrade scripts that call curl or shell from the GitLab service
Other platforms for CVE-2026-97229
Testing Methodology
Validate this detection against 1 adversary technique from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are further down this page.
- Test 1 Spawn a shell from a stand-in worker process (lab)
Expected signal: Process creation events for a puma binary executed from /tmp and a child sh and id.
Response Playbook
Triage
- Confirm the GitLab version is 19.2 before 19.2.8, 19.3 before 19.3.5 or 19.4 before 19.4.2, and whether the instance is reachable from the internet.
- Identify the time of the worker-spawned process or the suspicious CI/CD configuration request, the source IP and any project or pipeline it created or changed.
- Check whether the activity matches an administrator console session or an approved maintenance script.
Containment
- Upgrade to 19.2.8, 19.3.5 or 19.4.2 or later as soon as possible, per the GitLab patch release notice and CISA KEV guidance.
- Restrict external access to the instance while triaging, for example behind a VPN or allowlist, and disable open sign-up.
- Rotate CI/CD variables, runner tokens, deploy keys, and the secrets in gitlab-secrets.json if compromise is suspected.
Evidence Collection
- Preserve production_json.log, api_json.log, gitlab-rails and nginx access logs before rotation.
- Capture the process list, network connections and recent files owned by the git user on the GitLab host.
- Export recent pipelines, CI/CD configuration changes and audit events for the surrounding window.
Escalation Criteria
- !Escalate to incident response on any shell or download tool launched by a GitLab worker without a matching admin session.
- !Escalate if unknown projects, runners, tokens or admin users appear.
- !Escalate if CI/CD secrets may have been exposed and could be used against downstream systems.
Investigation Guide
Forensic Artifacts
- >
GitLab production_json.log, api_json.log and audit events - >
nginx or reverse proxy access logs for the instance - >
Files and processes owned by the git user on the GitLab host
Tuning Guidance
Allowlist known administrator hosts and change-managed maintenance jobs, and baseline legitimate pipelines that use long regular expressions in rules. The process-based rules are the higher-fidelity signal, while the request-pattern rule is a lower-fidelity hunting aid. Patching to a fixed release is the definitive fix.
Hunting Queries
Builds a 14-day baseline of worker-spawned shells and CI/CD configuration requests per source so bursts around the 2026-10-13 disclosure stand out.
// df00tech DF00-142016b516 · https://df00tech.com/detections/CVE-2026-97229 · licence: https://df00tech.com/detections/licence
Syslog | where TimeGenerated > ago(14d) | where ProcessName in~ ("puma", "sidekiq") | where SyslogMessage has_any ("/bin/sh", "/bin/bash", "curl ", "wget ") | summarize Events = count() by Computer, bin(TimeGenerated, 1d) | order by Computer asc, TimeGenerated asc ``` df00tech DF00-142016b516 · https://df00tech.com/detections/CVE-2026-97229 · licence: https://df00tech.com/detections/licence ```
index=gitlab sourcetype="gitlab:production_json" earliest=-14d (ci_config OR ".gitlab-ci") | timechart span=1d count by remote_ip Atomic Red Team Tests
Simulates the telemetry the process rules key on by launching a shell from a process named puma on a Linux lab host. This does not exploit the vulnerability. Run only on a lab host.
Command
cp /bin/sleep /tmp/puma && /tmp/puma 1; sh -c 'id' Cleanup
rm -f /tmp/puma Expected Telemetry
Process creation events for a puma binary executed from /tmp and a child sh and id.
Expected Detection
Process-based rules fire only if the parent is a GitLab worker running as the git user; this test exercises the process-name field mapping.