Apache Struts 2 Core 7.4.0 OGNL Code Execution
Description
Apache Struts2 Core version 7.4.0 and below attempt to prevent arbitrary code execution via Object-Graph Navigation Language (OGNL) through several different mechanisms but only in a cursory fashion -- the libraries only guard against immediate calls evaluated by the OGNL engine via `SecurityMemberAccess`, but an allowed call that, instead, accepts nested arguments and, itself, invokes reflection internally executes outside of the scope of said cursory protections, thereby enabling attackers to bypass the limited protections entirely.
It should be noted that this attack, obviously, only works in locations where the information system runs the input/output through an OGNL parser and executor. Moreover, there is a key difference between Struts2 Core 6.x and below and 7.x -- 7.x favours a whitelist-based approach that is coupled with some blacklisting, while 6.x and below only check a blacklist (if anything at all). This means that for successful exploitation in 6.x and below, attackers can simply find a call that uses reflection and that isn't explicitly blacklisted (e.g., `java.beans.Statement` and `java.beans.Expression`), embed the otherwise disallowed reflective call, and watch it run. In 7.x, however, attackers must use something that has been explicitly allowed, first, as the wrapper, which raises the bar for exploitation, reducing the likelihood for most systems running 7.x (if someone does not realise that the Struts2 Core library only provides cursory protections, they will not understand the risk and ma
y accidentally add something like `java.beans.Statement`), but does not reduce the impact or eliminate the risk.
Impact
Attackers can bypass the Apache Struts2 Core and OGNL library's protections against arbitrary code execution via malicious OGNL through nested calls, thereby executing arbitrary code on the information system. Importantly, through this, attackers can bypass not only the class/method checks, but also the static/non-static checks, allowing attackers to, for example, call to `ProcessBuilder`, dump the environment variables via `System.getenv(String)`, and various other such calls.
Steps to Reproduce
Sample Query
The following will work on Apache Struts2 Core versions 6.x and below (assuming that `query` runs through the OGNL parser, etc. -- this can happen on the request, but also if the string is reflected back in, say, a JSP via tags that do as such) without much effort. On Apache Struts2 Core 7.x, though, `java.beans.Expression` would need to be whitelisted, first.
GET /search.action?query=new+java.beans.Expression(new+java.beans.Expression(%40java.lang.ProcessBuilder%40class,'new',new+Object%5B%5D%7Bnew+String%5B%5D%7B'/bin/sh','-c','id+%3E+%3C%3CREPLACE+ME+--+a+fresh+marker+file+path%3E%3E'%7D%7D).getValue(),'start',new+Object%5B0%5D).getValue()
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
01 Nov 2026 00:00Current
7.1High risk
Vulners AI Score7.1