Skip to content
CVE-2026-97229 Elastic Security · Elastic

Detect GitLab CE/EE Unauthenticated RCE via Crafted CI/CD Regular Expression (CVE-2026-97229) in Elastic Security

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

Elastic Detection Query

Elastic Security (Elastic)
eql
// df00tech DF00-142016b516 · https://df00tech.com/detections/CVE-2026-97229 · licence: https://df00tech.com/detections/licence
process where event.type == "start" and process.parent.name : ("puma*", "sidekiq*", "ruby", "gitlab-rails") and process.name : ("sh", "bash", "curl", "wget", "nc", "python*", "perl") and user.name : "git"
critical severity medium confidence

EQL rule for a shell, interpreter or download tool started by the GitLab Rails, Puma or Sidekiq workers under the git service account.

Data Sources

Elastic Agent or Auditbeat process events from the GitLab host

Required Tables

logs-endpoint.events.process-*auditbeat-*

False Positives & Tuning

  • Git hooks and server-side scripts invoked by Sidekiq
  • Administrators using gitlab-rails runner

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.

  1. 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

  1. 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.
  2. 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.
  3. Check whether the activity matches an administrator console session or an approved maintenance script.

Containment

  1. 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.
  2. Restrict external access to the instance while triaging, for example behind a VPN or allowlist, and disable open sign-up.
  3. Rotate CI/CD variables, runner tokens, deploy keys, and the secrets in gitlab-secrets.json if compromise is suspected.

Evidence Collection

  1. Preserve production_json.log, api_json.log, gitlab-rails and nginx access logs before rotation.
  2. Capture the process list, network connections and recent files owned by the git user on the GitLab host.
  3. 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.

Hunting — KQL
kql
// 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
Hunting — SPL
spl
``` 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

Test 1 Spawn a shell from a stand-in worker process (lab)
linux

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

bash
cp /bin/sleep /tmp/puma && /tmp/puma 1; sh -c 'id'

Cleanup

bash
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.

Related Detections