Cloudanix VulnDB

CVE-2026-41316

High · 8.1

CVSS

8.1

EPSS

1.3%

Published

Apr 24, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A vulnerable Ruby component can let an attacker run commands on an application if the application accepts unsafe serialized data.

Chainable
Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
High
Impact
Remote Code Execution
Component
Library
Class
Deserialization
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

This is a Ruby ERB deserialization-to-code-execution flaw. Ruby ERB attempted to prevent code execution from deserialized ERB objects by checking an internal initialization guard in ERB#result and ERB#run, but other public methods that evaluate the ERB source using eval(), specifically ERB#def_method, ERB#def_module, and ERB#def_class, were not protected. If a Ruby application performs Marshal.load on attacker-controlled data while ERB is available, a crafted serialized object can bypass the guard and reach ERB#def_module as an evaluation sink, resulting in arbitrary Ruby code execution in the context of the application process.

Why it matters to the business

Successful exploitation can allow an unauthenticated remote attacker to run code inside a vulnerable Ruby application, potentially leading to data theft, service disruption, credential exposure, lateral movement, or full application compromise. The CVSS score is high, but exploitation depends on the application accepting untrusted Ruby Marshal data, which is less common and raises the attack complexity. EPSS is currently low and stable, and the issue is not listed in CISA KEV or known ransomware use, but exposed deserialization paths should still be treated as urgent because exploitation results in full code execution.

How an attack unfolds

An attacker first identifies a Ruby application endpoint, job processor, cache mechanism, session mechanism, message queue consumer, or API path that accepts data eventually passed into Marshal.load. The attacker then sends a crafted Ruby Marshal payload that reconstructs an ERB object with attacker-controlled template source and internal state. Because ERB#result and ERB#run contain an initialization guard, the attacker avoids those methods and instead relies on an unguarded public method such as ERB#def_module, which evaluates the stored ERB source. When application logic invokes or otherwise reaches that method on the deserialized object, Ruby evaluates the attacker-controlled source within the application process. From there, the attacker can execute commands, read application secrets, alter data, open outbound network connections, install persistence, or pivot to other systems using the compromised process privileges.

How to fix it

Upgrade ERB to a patched version: 4.0.3.1, 4.0.4.1, 6.0.1.1, 6.0.4, or later according to the version line in use. If ERB is bundled through Ruby or another framework dependency, update the Ruby runtime, bundled gems, lockfile, container image, and deployed artifacts so the patched ERB version is actually loaded at runtime. As a defense-in-depth measure, remove all uses of Marshal.load on untrusted or externally influenced data. Replace Ruby Marshal with safer formats such as JSON for simple data structures, or use safe deserialization APIs with strict type allowlists where applicable. If legacy Marshal use cannot be immediately removed, require cryptographic signing of serialized data, reject unsigned payloads, restrict accepted classes, isolate deserialization in a low-privilege process, and block external access to endpoints that accept serialized objects.

How to confirm the fix worked

Confirm the runtime ERB version is patched by checking the deployed gem or bundled library version, for example with dependency inventory, lockfile review, container image scanning, or runtime inspection of ERB::VERSION. Verify that no deployed application is still loading ERB versions below the patched releases. Review source code and dependencies for Marshal.load, Marshal.restore, or framework wrappers around Ruby Marshal and determine whether any input can be influenced by users, messages, cookies, caches, queues, or external services. After remediation, test that crafted or malformed Marshal payloads are rejected before deserialization and that application logs show controlled rejection rather than Ruby object reconstruction. Validate that production images, background workers, web processes, and scheduled jobs all run the same patched dependency set, not just the main web application.

Typical attack path

  1. Find a Ruby application or service that has ERB loaded and processes externally supplied serialized Ruby Marshal data.
  2. Send a probe or crafted serialized object to confirm that Marshal.load or equivalent unsafe deserialization is reachable.
  3. Craft a malicious serialized ERB object that bypasses the @_init guard by targeting an unguarded ERB evaluation method such as ERB#def_module.
  4. Trigger application behavior that calls the vulnerable ERB method after deserialization.
  5. Execute arbitrary Ruby code in the application process.
  6. Use the gained execution to read secrets, access data, spawn system commands, establish outbound connections, or move laterally.

How to detect it

Investigate whether vulnerable Ruby services accepted suspicious serialized input before patching. Review web server logs, application logs, API gateway logs, job queue payload logs, message broker traces, cache/session stores, and error trackers for requests or messages containing Ruby Marshal payload characteristics, especially binary Marshal headers or base64-encoded Marshal data. Ruby Marshal payloads often begin with the binary bytes 0x04 0x08 or appear base64-encoded with prefixes such as BAh. Look for errors or stack traces involving Marshal.load together with ERB methods such as def_module, def_method, or def_class. On hosts and containers, review EDR/process telemetry for Ruby application processes spawning shells or utilities such as sh, bash, curl, wget, nc, python, perl, openssl, or powershell. Review outbound network logs for unexpected connections initiated by Ruby application processes shortly after suspicious requests. Examine recent file modifications in application directories, temporary directories, cron locations, startup scripts, and writable web roots. If exploitation is suspected, collect application logs, request bodies where available, queue messages, container stdout/stderr, process execution history, environment variable access indicators, and any crash dumps or Ruby exception traces before redeploying or rotating evidence away.

  • Marshal.load
  • Marshal.restore
  • ERB#def_module
  • ERB#def_method
  • ERB#def_class
  • in `def_module'
  • in `def_method'
  • in `def_class'
  • in `load'
  • marshal data too short
  • incompatible marshal file format
  • \x04\x08
  • BAh
  • @src
  • @_init
  • ERB::VERSION
  • ruby -e
  • ruby -rerb
  • /bin/sh -c
  • /bin/bash -c
  • curl http
  • wget http
  • nc -e
  • /tmp/
  • /var/tmp/

What your security team should do

  • Prioritize patching Ruby applications that deserialize external, user-supplied, queued, cached, or cross-service data using Marshal.load.
  • Upgrade ERB to 4.0.3.1, 4.0.4.1, 6.0.1.1, 6.0.4, or later, and verify the patched version is present in deployed runtime artifacts.
  • Search code repositories and dependency code for Marshal.load, Marshal.restore, and ERB#def_module, ERB#def_method, or ERB#def_class usage.
  • Treat any externally reachable Marshal deserialization path as a critical exposure even though EPSS is currently low and no KEV listing exists.
  • Add detection for Ruby processes spawning shells, download utilities, scripting runtimes, or unexpected outbound connections.
  • Rotate application secrets if exploitation is suspected, because arbitrary Ruby execution can expose environment variables, credentials, signing keys, and configuration files.
  • Prefer removing unsafe Ruby Marshal deserialization over relying only on patching, because Marshal.load remains dangerous when processing untrusted data.

The record

ERB is a templating system for Ruby. Ruby 2.7.0 (before ERB 2.2.0 was published on rubygems.org) introduced an `@_init` instance variable guard in `ERB#result` and `ERB#run` to prevent code execution when an ERB object is reconstructed via `Marshal.load` (deserialization). However, three other public methods that also evaluate `@src` via `eval()` were not given the same guard: `ERB#def_method`, `ERB#def_module`, and `ERB#def_class`. An attacker who can trigger `Marshal.load` on untrusted data in a Ruby application that has `erb` loaded can use `ERB#def_module` (zero-arg, default parameters) as a code execution sink, bypassing the `@_init` protection entirely. ERB 4.0.3.1, 4.0.4.1, 6.0.1.1, and 6.0.4 patch the issue.

Affected packages

Ecosystem Package Introduced Fixed
openSUSE:Tumbleweed ruby4.0 0 4.0.3-1.1

Related vulnerabilities