Ruby has shipped versions 4.0.9, 3.4.12, and 3.3.13 to fix three memory-corruption bugs in Onigmo, the regular expression engine embedded in the Ruby interpreter. These are not obscure academic bugs: GitLab's security team traced four critical code-execution vulnerabilities — patched over the past month — directly back to these Onigmo flaws. A specially crafted regular expression pattern can corrupt memory while Ruby compiles the pattern, before a single byte of input is even matched, and that corruption can be weaponized into remote code execution on the server.
If you run self-hosted GitLab, any Ruby/Rails application that compiles user-influenced regex patterns, or any Ruby service exposed to the internet, treat this as a priority patching event. Regex compilation is a code path that a surprising number of applications expose to attackers — search filters, validation rules, routing logic, log parsing, and admin-configurable patterns all feed Regexp.new or literal pattern compilation.
Technical Analysis
What is Onigmo and why does it matter?
Onigmo is the fork of the Oniguruma regular expression library that has been baked into Ruby's interpreter since the Ruby 1.9 era. It is not an optional dependency — every Ruby process contains it, and every regex your application compiles goes through it. That means a bug in Onigmo is effectively a bug in every Ruby runtime on the planet, including the runtimes powering GitLab, countless Rails applications, CI/CD tooling, and internal automation scripts.
The vulnerability class
The critical detail in this disclosure is when the memory corruption occurs: at pattern compilation time. Most regex security guidance focuses on ReDoS (Regular Expression Denial of Service) — pathological backtracking that burns CPU at match time. This is a different and far more dangerous class. A malformed or specially crafted pattern corrupts memory during the compile phase, which means:
- Input sanitization at match time does nothing. The damage happens the moment the pattern is compiled, before any matching logic executes.
- Any code path that compiles attacker-influenced patterns is an RCE primitive. That includes
Regexp.new(user_input), interpolation into regex literals, dynamic route or validation builders, and GitLab's own internal use of patterns derived from user-supplied data (the vector GitLab patched in its four critical flaws). - WAF rules inspecting payloads won't reliably catch it. The pattern doesn't need to look like shellcode; it needs to look like a regex.
Affected versions and products
- Ruby — all releases prior to the fixed builds. Upgrade to 3.3.13, 3.4.12, or 4.0.9 depending on your release track.
- Self-hosted GitLab (CE/EE) — GitLab has already released patches for the four downstream critical flaws over the past month. If your GitLab instance is not on the latest patch release for its major version, you are exposed both at the GitLab application layer and at the underlying Ruby layer.
- Any application or gem that accepts regex patterns from untrusted input and compiles them server-side.
Exploitation status
GitLab's own security researchers demonstrated the exploitability path — pattern-driven memory corruption leading to code execution on GitLab's servers — which is why the downstream flaws were rated critical. The upstream Ruby fixes landing publicly means the technical details of the underlying Onigmo defects are now effectively disclosed to every attacker monitoring Ruby's release diffs. The window between public patch availability and working exploit reconstruction for interpreter-level bugs is historically short. No public PoC has been confirmed at time of writing, but the barrier to developing one has dropped sharply with this release. Do not wait for a CISA KEV listing to act.
Attack chain (defender's view)
- Attacker identifies an endpoint or feature that compiles user-controlled input into a regex (GitLab feature, app search filter, validation endpoint, API parameter).
- Attacker submits a crafted pattern string.
- Onigmo compiles the pattern; memory corruption occurs inside the Ruby interpreter process.
- Corruption is steered toward control-flow hijack → code execution with the privileges of the Ruby process (for GitLab, typically the
gituser with access to repositories, secrets, and CI tokens). - Post-exploitation: repository theft, CI pipeline poisoning, lateral movement via stored credentials.
Detection & Response
Regex-compilation memory corruption is hard to detect at the point of exploit — the malicious input looks like text. The practical detection surface is the aftermath: Ruby interpreter crashes, crash dumps, and post-exploitation behavior such as the Ruby/GitLab process spawning unexpected children. These are high-fidelity signals because production Ruby web processes almost never crash-loop and almost never spawn shells.
---
title: Ruby Process Spawning Shell or System Utility
title_case: Ruby process spawning suspicious child process
id: 3f7a2c91-4e5b-4d8a-9c1e-2b6f0a8d4e5f
status: experimental
description: Detects Ruby interpreter processes spawning shells or system utilities, consistent with post-exploitation activity following memory corruption or code execution in a Ruby application such as GitLab.
references:
- https://thehackernews.com/2026/10/ruby-fixes-three-regex-engine-bugs.html
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/10/15
tags:
- attack.execution
- attack.t1059
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/ruby'
- '/ruby3.3'
- '/ruby3.4'
- '/ruby4.0'
- '/puma'
- '/sidekiq'
- '/unicorn'
- '/rails'
selection_child:
Image|endswith:
- '/bash'
- '/sh'
- '/dash'
- '/zsh'
- '/curl'
- '/wget'
- '/python'
- '/python3'
- '/perl'
- '/nc'
- '/ncat'
- '/base64'
- '/id'
- '/whoami'
- '/cat'
condition: selection_parent and selection_child
falsepositives:
- GitLab housekeeping and backup jobs that legitimately shell out from Ruby workers
- Rails console administration and Rake tasks invoked by administrators
level: high
---
title: GitLab Rails Process Executing Unexpected Commands
id: 8c4d1e62-7a3b-4f59-b2d8-9e1c5a7f3d60
status: experimental
description: Detects the GitLab web or background job processes spawning command interpreters or download tools, a strong indicator of successful code execution against a self-hosted GitLab instance.
references:
- https://thehackernews.com/2026/10/ruby-fixes-three-regex-engine-bugs.html
- https://attack.mitre.org/techniques/T1203/
author: Security Arsenal
date: 2026/10/15
tags:
- attack.execution
- attack.t1203
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentCommandLine|contains:
- 'gitlab'
- 'puma'
- 'sidekiq'
- 'gitaly'
selection_child:
Image|endswith:
- '/bash'
- '/sh'
- '/curl'
- '/wget'
- '/nc'
- '/socat'
- '/python3'
- '/chmod'
- '/chown'
condition: selection_parent and selection_child
falsepositives:
- GitLab Omnibus maintenance scripts and chef reconfigure runs
- Legitimate git hooks and CI job execution (review parent lineage carefully)
level: critical
---
title: Ruby Interpreter Crash Artifacts on Web Servers
id: 5e9b3f47-2c8d-4a61-8f4c-6d2a9b0e1c35
status: experimental
description: Detects repeated Ruby process crashes or segfault indicators in syslog, which may indicate attempted or successful exploitation of Onigmo regex compilation memory corruption. Crash loops on production Ruby web processes are abnormal.
references:
- https://thehackernews.com/2026/10/ruby-fixes-three-regex-engine-bugs.html
- https://attack.mitre.org/techniques/T1499/
author: Security Arsenal
date: 2026/10/15
tags:
- attack.impact
logsource:
product: linux
service: syslog
detection:
selection:
- 'segfault'
- 'ruby'
keywords:
- 'segfault at'
- 'general protection fault'
- 'core dumped'
- 'SIGSEGV'
- 'BUG: Segmentation fault'
condition: keywords
falsepositives:
- Legitimate application bugs in development or staging environments
- Known unstable native gems (nokogiri, native extensions) on legacy systems
level: medium
// Hunt for shells and download tools spawned by Ruby/GitLab processes (Sentinel + Syslog/CEF)
// Tune the process list to your GitLab/Ruby deployment footprint
let suspiciousChildren = dynamic(["bash", "sh", "dash", "curl", "wget", "nc", "ncat", "python3", "perl", "socat"]);
union isfuzzy=true
(Syslog
| where SyslogMessage has_any ("puma", "sidekiq", "ruby", "gitlab")
| where SyslogMessage has_any (suspiciousChildren)
| extend ParsedChild = extract(@"(/[a-zA-Z0-9_\-\./]+/(bash|sh|curl|wget|nc|python3|perl))", 1, SyslogMessage)
| where isnotempty(ParsedChild)
| project TimeGenerated, Computer, ProcessName, SyslogMessage, ParsedChild),
(CommonSecurityLog
| where DeviceProcessName has_any ("bash", "sh", "curl", "wget", "nc", "python3")
| where Message has_any ("ruby", "puma", "sidekiq", "gitlab")
| project TimeGenerated, Computer, DeviceProcessName, Message)
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Count = count() by Computer, ProcessName
| order by Count desc;
-- Hunt for anomalous child processes of Ruby interpreters and GitLab workers
-- Deploy as a hunt across Linux servers hosting Ruby applications or GitLab
SELECT Pid,
Ppid,
Name AS ProcessName,
CommandLine,
Exe,
Username,
CreateTime
FROM pslist()
WHERE Ppid IN (
SELECT Pid
FROM pslist()
WHERE Name =~ '(?i)ruby|puma|sidekiq|unicorn|rails'
)
AND Name =~ '(?i)bash|sh$|dash|zsh|curl|wget|nc|ncat|python|perl|socat'
Bash: Verify Ruby version and inventory exposure
#!/bin/bash
# Ruby Onigmo exposure audit — run on every host running Ruby or self-hosted GitLab
# Checks interpreter version against the patched releases and inventories regex-facing code paths
echo "=== Ruby interpreter version ==="
if command -v ruby >/dev/null 2>&1; then
RUBY_VER=$(ruby -v)
echo "${RUBY_VER}"
echo "${RUBY_VER}" | grep -E 'ruby (3\.3\.13|3\.4\.12|4\.0\.9)' >/dev/null \
&& echo "[OK] Patched Onigmo release detected" \
|| echo "[VULNERABLE] Ruby is NOT on 3.3.13 / 3.4.12 / 4.0.9 — upgrade immediately"
else
echo "[INFO] No system ruby found; check container images and bundled runtimes separately"
fi
echo ""
echo "=== GitLab bundled Ruby (Omnibus) ==="
if [ -x /opt/gitlab/embedded/bin/ruby ]; then
/opt/gitlab/embedded/bin/ruby -v
gitlab-rake gitlab:env:info 2>/dev/null | head -20
echo "[ACTION] Apply the latest GitLab patch release — GitLab's four critical fixes ride on its own release train"
fi
echo ""
echo "=== Code paths compiling dynamic regex (top 40 hits) ==="
# Audit application code for patterns that may compile user-influenced regex
APP_DIRS="/srv /opt /var/www /home"
for d in ${APP_DIRS}; do
[ -d "${d}" ] && grep -rn --include='*.rb' -E 'Regexp\.new|Regexp\.compile|/.*#\{.*\}/' "${d}" 2>/dev/null | head -40
done
echo ""
echo "=== Recent Ruby segfaults in system logs ==="
journalctl --since "-14 days" 2>/dev/null | grep -iE 'segfault|ruby.*(sigsegv|core dumped)' | tail -20 \
|| grep -iE 'segfault|ruby' /var/log/syslog 2>/dev/null | tail -20
echo ""
echo "=== Listening Ruby processes ==="
ss -tlnp 2>/dev/null | grep -iE 'ruby|puma|unicorn|sidekiq'
Remediation
1. Patch Ruby immediately
Upgrade every Ruby runtime — system, rbenv/rvm-managed, container base images, and bundled runtimes — to the fixed releases:
- Ruby 3.3.x → 3.3.13
- Ruby 3.4.x → 3.4.12
- Ruby 4.0.x → 4.0.9
Official source: the Ruby project release announcements at https://www.ruby-lang.org/en/news/. Do not forget container images — rebuild any image pinned to an older Ruby base tag, and audit gem-bundled vendored runtimes in build pipelines.
2. Patch self-hosted GitLab (if you haven't already)
GitLab released patches for the four downstream critical flaws over the past month. Confirm your instance is on the latest patch release for your major version via https://about.gitlab.com/releases/categories/releases/ and the GitLab security release blog. GitLab's Omnibus package bundles its own Ruby, so the GitLab patch and the system Ruby patch are separate actions — both are required. Given GitLab's history as a prime target for mass exploitation (repo theft, CI secret harvesting), treat internet-facing GitLab instances as your highest-priority asset in this remediation cycle.
3. Eliminate attacker-controlled regex compilation
This is the durable fix beyond patching:
- Never compile raw user input into a regex. Replace user-supplied patterns with an allowlisted set of pre-compiled patterns, or use literal string matching (
String#include?,index) where regex isn't truly required. - Where dynamic patterns are unavoidable, validate against a strict character/length allowlist before compilation, wrap compilation in a timeout and error boundary, and consider running it in a sandboxed, low-privilege worker.
- Audit gems and internal code for
Regexp.new,Regexp.compile, and interpolated regex literals (/#{var}/) fed by request parameters — the audit script above gives you a starting inventory.
4. Compensating controls while patching
- Place strict request body and parameter size limits at the reverse proxy in front of Ruby applications (regex payloads for compile-time corruption can be small, so size limits are a partial mitigation only — patch remains the fix).
- Segment self-hosted GitLab off the public internet where business requirements allow (VPN/SSO gateway); GitLab instances are consistently among the first targets scanned after critical disclosures.
- Enable crash dump collection and alerting (
systemd-coredump,kernel.core_pattern) on Ruby hosts so exploitation attempts generate forensic evidence rather than silent restarts. - Review GitLab audit logs (
/var/log/gitlab/gitlab-rails/audit_json.log) and application logs for anomalous requests around the disclosure window, and hunt for the post-exploitation behaviors covered in the detections above.
5. Threat-model the blast radius
A compromised Ruby process on a GitLab server yields repositories, CI/CD variables, deploy keys, and runner tokens — a supply-chain compromise in a box. If you find evidence of exploitation, treat all secrets stored in GitLab CI/CD variables, protected branches, and runner registrations as compromised and rotate them. That rotation plan should be built now, not during the incident.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.