<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ERB — CraftedSignal Threat Feed</title><link>https://feed.craftedsignal.io/products/erb/</link><description>Trending threats, MITRE ATT&amp;CK coverage, and detection metadata — refreshed continuously.</description><generator>Hugo</generator><language>en</language><managingEditor>hello@craftedsignal.io</managingEditor><webMaster>hello@craftedsignal.io</webMaster><lastBuildDate>Sat, 25 Apr 2026 12:00:00 +0000</lastBuildDate><atom:link href="https://feed.craftedsignal.io/products/erb/feed.xml" rel="self" type="application/rss+xml"/><item><title>ERB Deserialization Bypass via def_module/def_method/def_class</title><link>https://feed.craftedsignal.io/briefs/2026-04-erb-deserialization/</link><pubDate>Sat, 25 Apr 2026 12:00:00 +0000</pubDate><author>hello@craftedsignal.io</author><guid isPermaLink="true">https://feed.craftedsignal.io/briefs/2026-04-erb-deserialization/</guid><description>A deserialization vulnerability exists in Ruby ERB versions before 4.0.3.1, version 4.0.4, ERB versions 5.0.0 before 6.0.1.1, and ERB versions 6.0.2 before 6.0.4. The `@_init` instance variable guard in `ERB#result` and `ERB#run` can be bypassed via `ERB#def_module`, `ERB#def_method`, and `ERB#def_class`, allowing arbitrary code execution when an ERB object is reconstructed via `Marshal.load` on untrusted data.</description><content:encoded><![CDATA[<p>Ruby versions before ERB 2.2.0 implemented an <code>@_init</code> instance variable guard in <code>ERB#result</code> and <code>ERB#run</code> to prevent code execution upon deserialization via <code>Marshal.load</code>. This guard is intended to block execution when an ERB object is reconstructed from untrusted data. However, the methods <code>ERB#def_method</code>, <code>ERB#def_module</code>, and <code>ERB#def_class</code> were not given the same protection, creating a bypass. An attacker capable of triggering <code>Marshal.load</code> on untrusted data in a Ruby application with the <code>erb</code> gem loaded can exploit <code>ERB#def_module</code> (using its zero-argument, default-parameter form) as a code execution sink. This bypass impacts Ruby on Rails applications that import untrusted serialized data, Ruby tools employing <code>Marshal.load</code> for caching or IPC, and legacy Rails applications (pre-7.0) utilizing Marshal for cookie session serialization. This bypass renders the <code>@_init</code> mitigation ineffective across all ERB versions from 2.2.0 through 6.0.3. Combined with the DeprecatedInstanceVariableProxy gadget (present in all ActiveSupport versions through 7.2.3), this enables a universal RCE gadget chain for Ruby 3.2+ applications using Rails. The vulnerability is identified as CVE-2026-41316.</p>
<h2 id="attack-chain">Attack Chain</h2>
<ol>
<li>The attacker crafts a malicious Ruby object containing an <code>ERB</code> instance and/or an <code>ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy</code> instance.</li>
<li>The <code>ERB</code> instance has its <code>@src</code> instance variable set to a string containing malicious code with the &ldquo;end\nsystem(&lsquo;id&rsquo;)\ndef x&rdquo; payload.</li>
<li>The vulnerable application calls <code>Marshal.load</code> on the crafted object, triggering deserialization.</li>
<li>During deserialization, the <code>DeprecatedInstanceVariableProxy</code> is instantiated (if used), which then invokes the <code>ERB#def_module</code> method via <code>method_missing</code>.</li>
<li>The <code>ERB#def_module</code> method calls <code>ERB#def_method</code> without checking the <code>@_init</code> guard.</li>
<li>Inside <code>ERB#def_method</code>, the malicious code in <code>@src</code> is wrapped in a method definition and evaluated via <code>module_eval</code>.</li>
<li>The &ldquo;end\nsystem(&lsquo;id&rsquo;)\ndef x&rdquo; payload causes the <code>system('id')</code> command to execute during the <code>module_eval</code> call, bypassing the intended deserialization protection.</li>
<li>The attacker achieves arbitrary code execution on the target system, gaining the ability to perform malicious actions.</li>
</ol>
<h2 id="impact">Impact</h2>
<p>Successful exploitation allows an attacker to execute arbitrary code on the target system. This affects Ruby applications, including Ruby on Rails, which use <code>Marshal.load</code> on untrusted data. Specific impact includes potential compromise of web servers and the ability to read sensitive files, modify data, or install malware. Vulnerable applications include those using <code>Marshal.load</code> for caching, data import, or IPC, and legacy Rails applications (pre-7.0) using Marshal for cookie session serialization. This bypass renders the @_init mitigation ineffective across all ERB versions from 2.2.0 through 6.0.3.</p>
<h2 id="recommendation">Recommendation</h2>
<ul>
<li>Upgrade your erb gem to version 4.0.3.1, 4.0.4.1, 6.0.1.1, or 6.0.4 to patch the vulnerability as described in the &ldquo;Patches&rdquo; section.</li>
<li>Avoid using <code>Marshal.load</code> on untrusted data, as it is inherently unsafe. Consider using alternative serialization formats like JSON or YAML.</li>
<li>Deploy the &ldquo;Detect ERB def_module Code Execution via Deserialization&rdquo; Sigma rule to detect exploitation attempts.</li>
</ul>
]]></content:encoded><category domain="severity">critical</category><category domain="type">advisory</category><category>deserialization</category><category>rce</category><category>ruby</category><category>rails</category></item></channel></rss>