GitLab CVE-2026-110264 — Unauthenticated RCE | Sentinel Threat Hunts

Threat Overview

GitLab published an out-of-band critical patch on October 21 for CVE-2026-110264, an integer overflow in the regular-expression compiler that can allow unauthenticated code execution under certain conditions. The vendor also published two detection concepts, 'Onigmo native worker crash' and 'Org mode render error burst.' This is separate from the earlier October 12 regex compiler issue CVE-2026-97229. GitLab has not published a universal exploit HTTP path, payload bytes, or attacker IOC; detection must focus on available crash/error telemetry and post-exploitation behaviors without treating ordinary `.org` requests as malicious.

References

GitLab critical patch release — October 21, 2026

GitLab published Onigmo worker-crash detection — October 21, 2026

GitLab published Org-mode error-burst detection — October 21, 2026

Censys vulnerability advisory — October 22, 2026

Impacted Systems

Vendor/product: GitLab Community Edition and Enterprise Edition, self-managed installations (Omnibus, source, container, Kubernetes/Helm). Affected: GitLab CE/EE all versions from 7.0 before the fixed release in their respective trains; 18.11 <18.11.13; 19.0 <19.0.10; 19.1 <19.1.9; 19.2 <19.2.9; 19.3 <19.3.6; 19.4 <19.4.3; 19.5 <19.5.1. Fixed: 18.11.13, 19.0.10, 19.1.9, 19.2.9, 19.3.6, 19.4.3, 19.5.1 (or later in applicable train). Exposure: network-reachable GitLab web service, including public projects where Org-mode content can be rendered; authentication is not required under documented conditions. Unaffected/patched: GitLab.com; GitLab Dedicated at 19.3.5-internal0 / 19.4.2-internal0 or later. Older unsupported trains require upgrade.

Why this matters

A compromised self-managed GitLab server can expose source repositories, CI/CD variables, deployment keys, and downstream software pipelines. The critical severity justifies rapid patching even without verified active exploitation.

Exploitation Status

GitLab confirmed the flaw and published patches on October 21, 2026. Its release notes point to two vendor-authored detection rules for Onigmo native worker crashes and Org-mode render-error bursts. Neither the vendor advisory nor other corroborated sources reviewed here establishes exploitation in the wild; the presence of an error burst alone is not proof of RCE.

What this hunt looks for

Layered Sentinel hunts cover confirmed indicators, product-scoped activity, and post-compromise behavior. Queries are not customer findings; detection confidence and missing telemetry are described below.

Required logs

CommonSecurityLog; DeviceFileEvents; DeviceProcessEvents; DeviceProcessEvents;DeviceNetworkEvents; Syslog

Hunt 1: GitLab-published Onigmo native worker crash symptoms

Required tables: Syslog | Signal: High. Based on GitLab-published detection category; exact GitLab log lines were not supplied in the advisory. Requires GitLab application/crash records forwarded to Syslog.

Syslog
| where TimeGenerated >= ago(14d)
| where SyslogMessage contains "Onigmo" or (SyslogMessage contains "regexp" and SyslogMessage has_any ("segfault", "crash", "overflow"))
| where ProcessName has_any ("gitlab", "puma", "ruby", "gitaly") or SyslogMessage contains "gitlab"
| project TimeGenerated, Computer, ProcessName, SeverityLevel, SyslogMessage
| order by TimeGenerated desc

Hunt 2: GitLab Org-mode render-error bursts

Required tables: Syslog | Signal: Medium. Generic approximation of GitLab’s Org-mode render-error-burst detection; not a reproduction of the vendor rule. Requires relevant application errors forwarded to Syslog.

Syslog
| where TimeGenerated >= ago(14d)
| where ProcessName has_any ("gitlab", "puma", "ruby") or SyslogMessage contains "gitlab"
| where SyslogMessage contains "org" and SyslogMessage has_any ("render", "regexp", "error", "exception")
| summarize Errors=count(), Examples=make_set(SyslogMessage,5), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by Computer, bin(TimeGenerated,5m)
| where Errors >= 5
| order by Errors desc

Hunt 3: GitLab Puma/Ruby web worker launches suspicious shell

Required tables: DeviceProcessEvents | Signal: High. High-signal post-RCE behavior, but legitimate GitLab CI/Runners should be excluded by identifying actual server hosts and worker ancestry.

DeviceProcessEvents
| where TimeGenerated >= ago(14d)
| where InitiatingProcessFileName in~ ("ruby", "ruby.exe", "puma", "puma.exe")
| where InitiatingProcessCommandLine contains "puma" or InitiatingProcessCommandLine contains "gitlab"
| where FileName in~ ("sh", "bash", "dash", "curl", "wget", "python", "python3", "nc", "socat")
| where ProcessCommandLine has_any ("/dev/tcp/", "curl", "wget", "base64", "chmod", "nohup", "nc -", "socat", "id", "whoami")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName
| order by TimeGenerated desc

Hunt 4: GitLab web worker creates executable payload in temporary path

Required tables: DeviceFileEvents | Signal: High. Conditional on Linux EDR collecting web-worker file writes. Not every exploit drops a file.

DeviceFileEvents
| where TimeGenerated >= ago(14d)
| where FolderPath startswith "/tmp/" or FolderPath startswith "/var/tmp/"
| where InitiatingProcessFileName in~ ("ruby", "puma")
| where InitiatingProcessCommandLine contains "puma" or InitiatingProcessCommandLine contains "gitlab"
| where FileName endswith ".sh" or FileName endswith ".py" or FileName endswith ".elf" or FileName endswith ".so"
| project TimeGenerated, DeviceName, ActionType, FolderPath, FileName, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256
| order by TimeGenerated desc

Hunt 5: GitLab-origin shell connects to public IP

Required tables: DeviceProcessEvents;DeviceNetworkEvents | Signal: High. Exact process-ID and creation-time correlation limits false positives; child process may use an intermediate interpreter not captured by the first parent.

let WebShells=DeviceProcessEvents
| where TimeGenerated >= ago(14d)
| where InitiatingProcessFileName in~ ("ruby", "puma")
| where InitiatingProcessCommandLine contains "puma" or InitiatingProcessCommandLine contains "gitlab"
| where FileName in~ ("sh", "bash", "dash", "python", "python3", "nc", "socat")
| project DeviceId, DeviceName, ShellPID=ProcessId, ShellStart=ProcessCreationTime, ShellTime=TimeGenerated, ShellName=FileName, ShellCommand=ProcessCommandLine;
DeviceNetworkEvents
| where TimeGenerated >= ago(14d)
| where RemoteIPType =~ "Public" and isnotempty(RemoteIP)
| project DeviceId, NetTime=TimeGenerated, InitiatingProcessId, InitiatingProcessCreationTime, RemoteIP, RemotePort, RemoteUrl
| join kind=inner WebShells on DeviceId, $left.InitiatingProcessId==$right.ShellPID
| where InitiatingProcessCreationTime==ShellStart and NetTime between (ShellTime..ShellTime+30m)
| project ShellTime, NetTime, DeviceName, ShellName, ShellCommand, RemoteIP, RemotePort, RemoteUrl
| order by NetTime desc

Hunt 6: GitLab-related cron or SSH authorized-key changes in Linux logs

Required tables: Syslog | Signal: Medium. Only visible if Linux audit/service logs actually include file-change or command context; legitimate GitLab maintenance may appear.

Syslog
| where TimeGenerated >= ago(14d)
| where SyslogMessage has_any ("authorized_keys", "crontab", "cron.d", "systemd")
| where SyslogMessage has_any ("gitlab", "git", "puma", "ruby") or Computer contains "gitlab"
| project TimeGenerated, Computer, ProcessName, SyslogMessage
| order by TimeGenerated desc

Hunt 7: Explicit CVE-2026-110264 WAF/IPS detections

Required tables: CommonSecurityLog | Signal: Medium. Only works if an IPS/WAF vendor exports an explicit matching signature. No signature is assumed to exist.

CommonSecurityLog
| where TimeGenerated >= ago(14d)
| extend Evidence=strcat(tostring(DeviceEventClassID)," ",tostring(Activity)," ",tostring(Message)," ",tostring(AdditionalExtensions))
| where Evidence contains "CVE-2026-110264" or (Evidence contains "GitLab" and Evidence contains "Org mode" and Evidence has_any ("exploit", "attack", "blocked"))
| project TimeGenerated, SourceIP, DestinationIP, DestinationHostName, DeviceVendor, DeviceProduct, DeviceAction, DeviceEventClassID, Message
| order by TimeGenerated desc

Detection Notes

Highest-signal post-compromise: GitLab Puma/Ruby web-worker ancestry launching a shell and exact process-to-network correlation. GitLab's Onigmo/Org-mode concepts are stronger pre-execution indicators if exact GitLab application/crash logs are ingested; the provided Syslog queries are conservative approximations, not the vendor's original detection code. Standard Syslog often omits application render errors. GitLab CI runners legitimately execute shells; separate GitLab server web-worker activity from CI runner workloads. No verified HTTP exploit payload or IOC is available, and firewall traffic-only logs cannot establish RCE.

Visibility is limited to telemetry actually ingested into Microsoft Sentinel; no customer workspace was queried for this publication.

Leave a Reply