ERB patches deserialization guard bypass enabling code execution
TL;DR — A Ruby ERB deserialization gadget can bypass a safety guard and reach arbitrary code execution when Marshal.load processes attacker-controlled data in environments that load both erb and activesupport.
What happened
ERB is Ruby’s templating engine (commonly used implicitly by Ruby on Rails) for rendering templates into executable Ruby code.
On April 21, 2026, Ruby published a security advisory for CVE-2026-41316, describing a deserialization vulnerability in ERB’s @_init guard. Per the advisory, ERB tries to prevent code execution when ERB objects are reconstructed via Marshal.load on untrusted data, but ERB#def_method, ERB#def_module, and ERB#def_class evaluate the template source without checking the guard. This enables an attacker who controls data passed to Marshal.load to bypass the protection and execute arbitrary code.
The advisory specifically calls out def_module as especially useful in gadget chains because it takes no arguments, making it straightforward to trigger during deserialization. This is notable because Marshal.load gadget chains remain a recurring, high-impact class of RCE in Ruby ecosystems whenever untrusted serialized data enters application boundaries (imports, caches, IPC, and legacy session serialization).
Who is impacted
- Any Ruby application that calls
Marshal.loadon untrusted data and has botherbandactivesupportloaded. - The advisory explicitly includes:
- Ruby on Rails applications importing untrusted serialized data (caching, data import, IPC).
- Ruby tools importing untrusted serialized data (caching, data import, IPC).
- Legacy Rails apps (pre-
7.0) that still use Marshal for cookie session serialization.
| Component | Affected versions (per advisory) | Patched versions (per advisory) |
|---|---|---|
erb (gem) | 6.0.3 or lower | 4.0.3.1, 4.0.4.1, 6.0.1.1, 6.0.4 or later |
What to do now
- Follow vendor remediation guidance:
We recommend upgrading the erb gem. Please update the erb gem to version 4.0.3.1, 4.0.4.1, 6.0.1.1, 6.0.4 or later.
- Inventory where
Marshal.loadis used across services, jobs, and tooling (especially cache layers, import/export paths, and IPC boundaries), and determine whether any of those inputs can be attacker-controlled. - Treat any
Marshal.loadusage on data that can cross trust boundaries as a code-execution risk: scope and audit deserialization entrypoints, and review for unexpected invocations of ERB-related methods during object reconstruction. - If compromise is suspected, review logs and artifacts around the deserialization entrypoint(s) and rotate credentials accessible to the affected runtime.
Content is AI-assisted and reviewed by our team, but issues may be missed and best practices evolve rapidly, send corrections to [email protected]. Always consult official documentation and validate key implementation decisions before making design or security choices.
