Skip to content

Apache Struts 2 Namespace (CVE-2018-11776) Vulnerability

Apache Struts 2 Namespace (CVE-2018-11776) Vulnerability

Published on

Click here to try hacking the Struts 2 Vulnerability and learn more with HackEDU's hands-on Struts 2 application.

Introduction

On 22 August 2018, a Semmle security researcher disclosed a critical vulnerability affecting the versions 2.3 to 2.3.34 and 2.5 to 2.5.16 of Apache Struts 2, one of the most used Java-based web application frameworks.

Impact

This unauthenticated Remote Code Execution vulnerability is easily triggered by visiting a specially crafted URL which allows the attacker to fully control the code executed on the server. This exploit requires a specific configuration that is not present on all Struts 2 applications, however, it does exist in commonly seen configurations for some Struts plugins.

According to Semmle, two requirements should be satisfied by an application to be vulnerable:

  • The alwaysSelectFullNamespace flag must be set to true in the Struts configuration.
  • The configuration file of the web application must contain an url or an action tag that either specifies a wildcard namespace or it does not specify a namespace at all.

Before discussing how you can identify and exploit this flaw, let's have a look at the technologies which accidentally produced the vulnerability. This will help you understand the vulnerabilities root cause.

What is Struts 2?

Apache Struts 2 is a free, open-source framework providing an Model-View-Controller (MVC) architecture for web application development. RedMonk analyst Fintan Ryan stated that in 2017 at least 65 percent of the Fortune 100 companies used Apache Struts 2 as a framework for their web applications.

What is the Object Graph Notation Language (OGNL)?

Apache Struts 2 initial release announced several important features and technologies that were added to the framework, making it considerably more efficient compared to the previous version. One of these features is the Object Graph Notation Language (OGNL), a template engine whose purpose is to create the views by transforming input parameters into OGNL statements and run them on a model.

As OGNL is very powerful, it quickly became a point of interest for attackers. A significant percentage of Struts 2 vulnerabilities occurred due to this technology, allowing attackers to execute malicious OGNL statements.

Struts2 Vulnerability Explanation

The vulnerability occurs because Struts insufficiently validates the user specified value of a namespace in the core of the framework.

What is a namespace?

A namespace is a concept used by the Struts 2 framework to group actions into logical modules so that two or more actions with the same name can exist in different namespaces.

Consequently, each namespace can have its own "menu" or "help" action, each with its own implementation (Read more in the Struts 2 Developer Guide).

An example is:

<action name="/editUser" class="org.apache.struts.webapp.example.EditUserAction">
<result>User.jsp</result>
</action>

<action name="/editSubscription" class="org.apache.struts.webapp.example.EditSubscriptionAction">
<result>Subscription.jsp</result>
</action>

<action name="/editRegistration" class="org.apache.struts.webapp.example.EditRegistrationAction">
<result>Registration.jsp</result>
</action>

What are the advantages of wildcard namespaces?

Instead of hard coding the configuration file, Java developers can use some patterns to achieve the same result.

For example using Wildcard Mappings, the above configuration can be re-factored to only three lines of code:

<action name="/edit*" class="org.apache.struts.webapp.example.Edit{1}Action">
<result>{1}.jsp</result>
</action>

The redirectAction result type uses ActionMapper interface to redirect the browser to a URL that invokes the specified action and (optional) namespace.

The best way to explain how Struts 2 ActionMapper interface works for the above configuration is to show a simplified workflow diagram for two cases. Let's suppose you make two simple GET requests.

Get Request 1 Diagram

Get Request 2 Diagram

Since the help action does not have a namespace parameter specified in struts.xml and the alwaysSelectFullNamespace flag is set to true, Struts uses everything between the domain name and the last slash as a namespace. After that, it calls the translateVariables function to check whether the namespace is a string or an OGNL expression. In case the user has provided an ONGL expression, the doExecute method executes it and returns the result. That is where a user can submit code for execution.

Apache quickly implemented a patch for this vulnerability by adding the cleanNamespaceName method whose purpose is to check whether a namespace is valid or not based on a allowlist approach.