Detect GitLab CE/EE Unauthenticated RCE via Crafted CI/CD Regular Expression (CVE-2026-97229) in Splunk
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
SPL Detection Query
``` df00tech DF00-142016b516 · https://df00tech.com/detections/CVE-2026-97229 · licence: https://df00tech.com/detections/licence ```
index=gitlab (sourcetype="gitlab:production_json" OR sourcetype="gitlab:api_json" OR sourcetype="syslog") earliest=-24h
| eval regex_len=len(coalesce('params{}.value', uri_query, ""))
| where match(_raw, "(?i)(ci_config|\.gitlab-ci|regex|regexp)") AND (regex_len>2000 OR match(_raw, "(\([^)]*[+*][^)]*\)[+*]){2,}"))
| stats count AS events values(uri_path) AS paths latest(_time) AS lastSeen earliest(_time) AS firstSeen BY host, remote_ip
| convert ctime(firstSeen) ctime(lastSeen)
| sort - lastSeen Surfaces GitLab requests that touch CI/CD configuration with very long or nested-quantifier regular expressions, the input pattern needed to trigger CVE-2026-97229.
Data Sources
Required Sourcetypes
False Positives & Tuning
- Legitimate pipelines with long rules:if or only:refs regular expressions
- Security scanners fuzzing CI configuration
- Linting and CI-lint API calls from developer tooling
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.