Date: Tue, 19 Mar 2024 08:07:48 +0000 (UTC) Message-ID: <577014668.55982.1710835668883@cwiki-he-fi.apache.org> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_55981_1533287276.1710835668883" ------=_Part_55981_1533287276.1710835668883 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
A vulnerability introduced by wildcard matching mechanism or double evaluat=
ion of OGNL Expression allows remote command execution.
Who should read this |
All Struts 2 developers and users |
---|---|
Impact of vulnerability |
Remote command execution, remote server conte= xt manipulation, injection of malicious client side code |
Maximum security rating |
Critical |
Recommendation |
Developers should immediately upgrade to Struts 2.3.14.3 |
Affected Software |
Struts 2.0.0 - Struts 2.3.14.2 |
Reporter |
Jon Passki from Coverity Security Research La= boratory reported directly to security@struts.a.o and via blog p= ost |
CVE Identifier |
= |
Struts 2 allows define action mapping base on wildcards, like in example= below:
<action na= me=3D"*" class=3D"example.ExampleSupport"> <result>/example/{1}.jsp</result> </action>
If a request doesn't match any other defined action, it will be matched =
by *
and requested action name will be used to load JSP file b=
ase on the name of action. And as value of {1
} is threaten as =
an OGNL expression, thus allow to execute arbitrary Java code on server sid=
e. This vulnerability is combination of two problems:
TextParseUtil.translat=
eVariables
when combination of $
and %
ope=
n chars is used.Open the following url, resulting in dy=
namic action name resolution based on passed value of #foo
http://localh= ost:8080/example/%24%7B%23foo%3D%27Menu%27%2C%23foo%7D
http://localh= ost:8080/example/${#foo=3D'Menu',#foo}
As you can notice, action name is resolved based on user input and you c= an put any arbitrary code to perform attack.
Open example.xml present in the Struts = Blank App and change result of HelloWorld action to one below:
<result ty= pe=3D"httpheader"> <param name=3D"headers.foobar">${message}</param> </result>
Open HelloWorld.java and change e=
xecute()
method as below:
public String= execute() throws Exception { return SUCCESS; }
Open the following url (you must have a= tool to check response headers)
http://localh= ost:8080/example/HelloWorld.action?message=3D%24{%25{1%2B2}}
http://localh= ost:8080/example/HelloWorld.action?message=3D${%{1+2}}
foobar
header, it should be 3
<=
/li>
As you can notice, passed value of message
parameter was us=
ed to set value of foobar
header and the value was double eval=
uated - first time when ${message
} was evaluated, secondly whe=
n parsed value (${%{1+2
}}) was evaluated again.
With the new version actions' names whitelisting was introduced and by d= efault is set to accept actions that match the following regex:
[a-z]*[A-Z]*[= 0-9]*[.\-_!/]*
user can change the definition by setting up a new constant in struts.xm= l as below:
<constant = name=3D"struts.allowed.action.names" value=3D"[a-zA-Z]*" />
Double evaluation of passed expression was removed from OgnlTextPa=
rser
which is used by TextParseUtil.translateVariables
.=
Backward Compatibility
There should be no problems with migration from previous version.
It is strongly recommended to upgrade to Struts 2.3.14.3.