← Verdict cards Cutsign
Patch lane No exploitation reported Public PoC circulating Not in KEV as of 2026-10-23

GitLab 19.5.1 critical release

CVSS 10.0 unauthenticated RCE — CVE-2026-110264, an integer overflow compiling a crafted regular expression in the bundled Onigmo engine. Reaches every self-managed release since 7.0 (2014). Patched October 21.

On Cutsign: brief story 10-22 CISO card news & updates (live) IoC card: none — no indicators published

Verdict: patch lane, urgent tier — and beware the patch trap. The October 12 patch releases (for CVE-2026-97229 and others) do not cover this flaw: anyone who "already patched GitLab this month" before October 21 is still exploitable. No exploitation reported yet, but public PoC code is circulating, preconditions are undisclosed (assume reachable), and GitLab offers no workaround. GitLab.com and Dedicated tenants are already fixed — this is a self-managed problem.

30-second read

A crafted regex fed to the Onigmo engine overflows during compilation, giving unauthenticated remote code execution on self-managed GitLab — one public write-up demonstrates the path through a crafted Org-mode file render. GitLab patched its vendored copy rather than waiting on upstream, and has not disclosed which endpoints reach the compiler, so treat every unauthenticated surface as in scope. A PoC repository is public on GitHub (unverified — handle in a sandbox, never on infrastructure).

Fixed versions — October 21, 2026

LineUpgrade to
19.519.5.1
19.4 / 19.3 / 19.2 / 19.1 / 19.019.4.3 / 19.3.6 / 19.2.9 / 19.1.9 / 19.0.10
18.11 (and every release back to 7.0)18.11.13 — older lines must jump forward

Exposed if

  • Self-managed GitLab below the fixed versions — including instances patched on the Oct 12 cycle
  • Internet-facing self-managed instances, first: unauthenticated + preconditions undisclosed

Not exposed if

  • GitLab.com (already runs fixed code)
  • GitLab Dedicated on 19.3.5-internal0 / 19.4.2-internal0 or later
  • Self-managed on a fixed version above

Detection coverage — as of Oct 23

CategoryVendorStatus
VendorGitLabPatched + rules published — fixes across seven version lines Oct 21; no workaround and preconditions undisclosed; two Sigma detections against GitLab application logs: "Onigmo native worker crash" and "Org mode render error burst" — run both back to Oct 20. Release post moved in their docs reorg; patch feed: docs.gitlab.com/releases/patch-releases.xml
VM scannersQualys / Tenable / Rapid7Nothing published found for this CVE as of Oct 23 — version checks will come; verify in each console before relying on scan results
SIEM contentSOC PrimeAnalysis published; rule content behind their platform
CommunityGitHub / NucleiPoC public (OppositDeer repo and mirrors — unverified, treat as hostile); no Nuclei template found yet
KEVCISANot listed as of Oct 23

Do now

  • Inventory self-managed GitLab — including "someone's team runner box" instances outside central management
  • Upgrade to the fixed version for the line; do not count Oct 12 patches as done
  • Run GitLab's two Sigma rules over application logs back to Oct 20
  • Internet-facing instances that cannot patch today: restrict unauthenticated access at the edge until they can

Escalation triggers

  • Exploitation in the wild reported, or CISA KEV listing
  • Hits on either Sigma rule (worker crashes / render-error bursts)
  • PoC matured into a weaponized exploit with disclosed preconditions

Inferred detections — while you wait

GitLab named two Sigma rules but the rule text is not in public sources, and scanners have nothing. The logic below reconstructs what those rules must look for, inferred from the flaw's shape (crafted regex → Onigmo crash during compile) — tune before trusting. These catch failed attempts; a clean exploit may leave neither.

Worker-crash canary — regex engine overflows crash Ruby workers before they succeed:


# host telemetry on GitLab servers
process.name IN (ruby, puma, sidekiq, gitlab-workhorse)
termination.signal = SIGSEGV
→ any occurrence on a GitLab host since Oct 20 is worth a look

Render-endpoint error bursts — the demonstrated path is a crafted Org-mode file render ("Org mode render error burst"):


# GitLab production_json.log / LB logs
status = 500 AND (path contains preview_markdown OR render OR blob
  OR requested file extension = .org)
| bucket 10m, count by src_ip → alert on bursts from a single source

Pre-patch inventory sweep — find the instances nobody registered:


# network / asset data
HTTP responses with header X-GitLab-* OR title "GitLab" on internal ranges
→ cross-check each against the fixed-version table above

Splunk (index=*) / Elastic ES|QL (FROM logs-*) — CIM Endpoint / Web field names for Splunk, ECS for Elastic; GitLab's own JSON logs carry status and path; tune to your add-on or integration:


# worker-crash canary on GitLab hosts
index=* earliest=-30d@d (process_name IN ("ruby","puma","sidekiq","gitlab-workhorse") OR "puma" OR "sidekiq") ("SIGSEGV" OR signal="SIGSEGV" OR "segfault")
| stats count min(_time) as first max(_time) as last by host process_name

# render-endpoint error bursts (production_json.log or the load balancer)

index=* earliest=-30d@d status=500 (path="*preview_markdown*" OR uri_path="*preview_markdown*" OR path="*/render*" OR path="*/blob/*" OR path="*.org" OR uri_path="*.org")
| eval src=coalesce(remote_ip, src)
| bin _time span=10m
| stats count by _time src
| where count>10

# pre-patch inventory: GitLab instances answering on internal ranges

index=* earliest=-7d@d ("X-Gitlab-Feature-Category" OR "X-GitLab-Meta" OR server="nginx" "GitLab")
| stats dc(dest) as instances values(dest) as hosts


// worker-crash canary on GitLab hosts
FROM logs-*
| WHERE @timestamp > NOW() - 30 days
| WHERE (process.name IN ("ruby", "puma", "sidekiq", "gitlab-workhorse") OR message LIKE "*puma*" OR message LIKE "*sidekiq*")
    AND (message LIKE "*SIGSEGV*" OR message LIKE "*segfault*")
| STATS count = COUNT(*), first = MIN(@timestamp), last = MAX(@timestamp) BY host.name, process.name

// render-endpoint error bursts (production_json.log or the load balancer)

FROM logs-*
| WHERE @timestamp > NOW() - 30 days AND http.response.status_code == 500
| WHERE url.path LIKE "*preview_markdown*" OR url.path LIKE "*/render*" OR url.path LIKE "*/blob/*" OR url.path LIKE "*.org"
| EVAL src = COALESCE(client.ip, source.ip)
| STATS count = COUNT(*) BY t = BUCKET(@timestamp, 10 minute), src
| WHERE count > 10

// pre-patch inventory: GitLab instances answering on internal ranges

FROM logs-*
| WHERE @timestamp > NOW() - 7 days
| WHERE message LIKE "*X-Gitlab-Feature-Category*" OR message LIKE "*X-GitLab-Meta*" OR (message LIKE "*nginx*" AND message LIKE "*GitLab*")
| STATS instances = COUNT_DISTINCT(destination.address), hosts = VALUES(destination.address)

Timeline

Sources

The Hacker News — CVSS 10.0 GitLab flaw · SOC Prime analysis · Astra — technical explainer · Konfirmity — fixed versions · GitLab release notes (vendor — release post moved in their docs reorg; patch feed: docs.gitlab.com/releases/patch-releases.xml)

Public OSINT only — contains no internal data Marcus Liberto · source Lane and triggers per CIRT triage-flow draft Tracked story: Cutsign 10-22