Author: 0day Rubbish Research Team (advisory produced by an automated multi-LLM ensemble — the project credits Claude, OpenAI, DeepSeek, and GLM)
Published: 2026-08-02
Source: https://0day-rubbish.com/blog/apache-struts2-restful-mapper-ognl-rce
Summary
An advisory from the 0day Rubbish project reports an unauthenticated remote code execution chain in Apache Struts 2 6.11.0 (and earlier 6.x releases that have not enabled the new allowlist sandbox). The chain is not present by default: it requires an opt-in but documented configuration — the REST action mapper (struts.mapper.class=restful) together with a wildcard action (<action name="*">) and a result location that uses {1} substitution. Under those conditions, attacker-supplied OGNL metacharacters in the request path reach an OGNL evaluation sink and, via a reported java.beans sandbox-bypass primitive, execute OS commands as the JVM user. The authors assign a self-rated CVSS of 9.8. No CVE identifier is assigned to this issue in the advisory (it references the historical S2-057 / CVE-2018-11776 only as background). The advisory is AI-generated and its verification carries a caveat noted below.
Technical Details
The stated root cause is a sanitization gap: RestfulActionMapper.getMapping() extracts the action name as a raw URI substring and returns it without calling cleanupActionName — the character-set gate ([a-zA-Z0-9._!/\-]*) that DefaultActionMapper adopted after S2-057 to reject OGNL metacharacters such as %, {, }, @, and #. That gate, the advisory says, was never mirrored into the REST mapper, so those characters pass through unsanitized.
With a wildcard action and a result such as /echo/{1}, the polluted action name is substituted into the result location and then evaluated as OGNL by StrutsResultSupport.conditionalParse → TextParseUtil.translateVariables — a path the advisory states does not run through the AcceptedPatternsChecker/ExcludedPatternsChecker allow/deny lists. The authors report confirming OGNL evaluation with a benign arithmetic probe before reaching command execution. The second half of the chain is described as a previously unrecorded sandbox bypass: because Struts’ SecurityMemberAccess excludes java.lang.Runtime, java.io, javax, and similar, but not the java.beans package, an attacker can use java.beans.Expression/Statement whose internal Method.invoke reflection is not re-checked by the OGNL sandbox, reaching Runtime.exec indirectly. Static-field access (needed to obtain the Runtime class object) is a framework default. This summary intentionally omits the full copy-paste payload; the advisory contains it.
Impact
As reported, a single unauthenticated GET request yields arbitrary OS command execution as the JVM process user; on appliance-style deployments that run the servlet container as root, that is full host compromise. The precondition is the opt-in REST-mapper + wildcard-dispatch + {1} configuration rather than a default install, so not every Struts 2 deployment is affected — but the affected pattern is described as common in REST-style Struts applications, and Struts’ wide deployment across finance, government, telecom, and enterprise IT gives a configuration-gated framework RCE a large potential blast radius. Affected per the source: Struts 2 6.11.0 and earlier 6.x without the allowlist enabled.
Mitigation
The advisory reports that Struts 7.3.0 is not exploitable by default: its default struts.allowlist.enable=true switches the OGNL sandbox to an allowlist model on which java.beans does not appear, blocking the bypass (the mapper sanitization gap reportedly still exists there, but the sandbox stops the chain). For 6.x, the authors recommend: avoid the vulnerable configuration; add java.beans to struts.excludedPackageNames; call cleanupActionName in RestfulActionMapper.getMapping() so the REST mapper matches DefaultActionMapper; route result-location translateVariables evaluation through AcceptedPatternsChecker (or disable %{} evaluation in result locations); and consider backporting the 7.3.0 allowlist default. Operators who cannot change configuration immediately should treat the REST-mapper + wildcard + {1} combination as exposed.
Verification caveat: the advisory states the chain was dynamically verified with uid=0(root), but on a lab setup using a Struts 6.10.0 jar as a “behavior proxy” for 6.11.0 (Tomcat 9.0.106, OGNL 3.3.5, JVM as root), which the authors assert is equivalent for the relevant classes rather than testing 6.11.0 directly. As with all AI-generated advisories, the CVSS is self-assigned and the affected-version, root-cause, and fix claims are as stated by the source and are not independently confirmed here.