[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FD] Apache Struts2 Core Arbitrary Code Execution via OGNL Sandbox Escape
- To: "fulldisclosure@xxxxxxxxxxxx" <fulldisclosure@xxxxxxxxxxxx>
- Subject: [FD] Apache Struts2 Core Arbitrary Code Execution via OGNL Sandbox Escape
- From: Daniel Owens via Fulldisclosure <fulldisclosure@xxxxxxxxxxxx>
- Date: Sun, 1 Nov 2026 22:23:31 +0000
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/