The Struts2 REST plugin vulnerability (S2-052) affects versions 2.1.2 to 2.3.33 and 2.5 to 2.5.12. It allows remote code execution via XStream deserialization when the plugin processes XML content. By sending a request with an XML extension or Content-Type header, attackers can specify arbitrary class names in XML tags, leading to command execution. The fix in Struts 2.5.13 adds a deserialization whitelist, but may break existing functionality.
Struts2-Rest-Plugin is a plugin that enables Struts2 to expose RESTful APIs. It determines the incoming data format based on the Content-Type header or URI extension, using the following mapping table:
Extension
Content-Type
Parsing Method
xml
application/xml
xstream
json
application/json
jsonlib or jackson (optional)
xhtml
application/xhtml+xml
None
None
application/x-www-form-urlencoded
None
None
multipart/form-data
None
jsonlib cannot introduce arbitrary objects, whereas xstream, by default (for versions prior to 1.5.x), is capable of introducing arbitrary objects. This is done by directly specifying the fully qualified class name to instantiate via the XML tag name:
Therefore, we can leverage deserialization to inject arbitrary classes, leading to a remote command execution vulnerability — all we need is to find a suitable gadget that works within the Struts2 library.
Vulnerability Reproduction
After starting the environment, visit http://your-ip:8080/orders.xhtml to see the showcase page. Since the rest-plugin determines the parsing method based on the URI extension or Content-Type header, we can simply change orders.xhtml to orders.xml in the URI, or set the Content-Type header to application/xml, and then pass XML data in the request body.
If the above packet executes successfully, it will create a file at /tmp/success inside the Docker container. Run docker compose exec struts2 ls /tmp/ to verify.
Additionally, we can also deploy a JSPX webshell:
There are other, even simpler exploitation methods, but we won't go into them here.
Vulnerability Fix
In Struts 2.5.13, following the mitigation measures recommended by xstream (http://x-stream.github.io/security.html), a whitelist was added for deserialization:
However, this may break existing business logic in legacy code, so upgrade with caution. There is no silver bullet — the only approach is to review old code piece by piece and remove any classes not on the whitelist.
S2-052 Remote Code Execution Vulnerability
Affected versions: Struts 2.1.2 - Struts 2.3.33, Struts 2.5 - Struts 2.5.12
Vulnerability Details:
Setting Up a Test Environment
Vulnerability Description
Struts2-Rest-Plugin is a plugin that enables Struts2 to expose RESTful APIs. It determines the incoming data format based on the Content-Type header or URI extension, using the following mapping table:
Extension
Content-Type
Parsing Method
xml
application/xml
xstream
json
application/json
jsonlib or jackson (optional)
xhtml
application/xhtml+xml
None
None
application/x-www-form-urlencoded
None
None
multipart/form-data
None
jsonlib cannot introduce arbitrary objects, whereas xstream, by default (for versions prior to 1.5.x), is capable of introducing arbitrary objects. This is done by directly specifying the fully qualified class name to instantiate via the XML tag name:
Therefore, we can leverage deserialization to inject arbitrary classes, leading to a remote command execution vulnerability — all we need is to find a suitable gadget that works within the Struts2 library.
Vulnerability Reproduction
After starting the environment, visit http://your-ip:8080/orders.xhtml to see the showcase page. Since the rest-plugin determines the parsing method based on the URI extension or Content-Type header, we can simply change orders.xhtml to orders.xml in the URI, or set the Content-Type header to application/xml, and then pass XML data in the request body.
Thus, the final packet to send is:
If the above packet executes successfully, it will create a file at /tmp/success inside the Docker container. Run docker compose exec struts2 ls /tmp/ to verify.
Additionally, we can also deploy a JSPX webshell:
There are other, even simpler exploitation methods, but we won't go into them here.
Vulnerability Fix
In Struts 2.5.13, following the mitigation measures recommended by xstream (http://x-stream.github.io/security.html), a whitelist was added for deserialization:
However, this may break existing business logic in legacy code, so upgrade with caution. There is no silver bullet — the only approach is to review old code piece by piece and remove any classes not on the whitelist.