The OGNL (Object Graph Navigation Library) is infamous for related vulnerabilities found in the Struts 2 framework that relies on it. But what is OGNL injection and how bad is it?
OGNL is an expression language for getting and setting the properties of Java objects, plus other extras such as list projection, selection, lambda expressions and method invocation. If an attacker can evaluate arbitrary OGNL expressions, they can execute arbitrary code on the application server and/or access and modify any value stored in the Struts 2 Value Stack.
Meder Kydyraliev from the Google Security Team reported the first public OGNL injections affecting Struts 2 back in 2010. After the first vulnerabilities were announced, Struts 2 provided an additional layer of protection by disabling static method invocation so that methods like java.lang.Runtime.exec() could not be executed. This protection was bypassed by Kydyraliev, who came up an OGNL expression that disabled the protection before running the arbitrary code.
Due to the severity of this vulnerability and the number of other vulnerabilities being reported at that time, Struts 2 decided to improve this protection by making the field that Kydyraliev targeted immutable in version 18.104.22.168, effectively disabling his payload.
We found that this modification is still easily by-passable using Java reflection trickery and recommend that developers do not rely solely on this last line of defense. It’s important to note that even if static methods calls were not allowed, an attacker would still be able to modify objects stored in the Value Stack , such as the “Session” instance, and cause severe damage to the running application and back end.
This is the reason Fortify still considers this vulnerability critical. Struts 2 is doing a great job patching security holes leading to OGNL injection in its framework’s code, but we cannot forget that using some Struts 2 APIs in the wrong way within our applications can open similar holes in our defenses.
Jon Passki from Coverity SRL, recently reported a vulnerability in the Apache Roller blogging application. Roller was passing untrusted user input to the Struts 2 ActionSupport.getText() method. Analyzing the data flow originating in the getText() argument all the way into Struts 2 framework code reveals that the data passed to getText() is eventually evaluated as an OGNL expression and it allows an attacker to execute arbitrary code on the application servers or modify the data structures stored in the Value Stack.
Fortify to the rescue
The Fortify Software Security Research group found that this is not an isolated case, and that many other Struts 2 API methods also lead to OGNL evaluations - meaning they should never be used with untrusted data.
One of these methods that we find particularly interesting is Request.getAttribute(). Struts 2 provides a request wrapper so that any lookup on the request’s attributes first searches the original attribute map and if not found there, evaluates the attribute being searched as an OGNL expression. So if the attribute name comes from an untrusted source, it leads to an OGNL injection.
There are many more API functions that evaluate their arguments as OGNL expressions and Fortify SCA can easily find and report them in case they are passed user-controlled data.
Beware of devmode
There are other situations that can allow an attacker to inject arbitrary OGNL expressions and don’t require the developers to pass untrusted data to these Struts 2 APIs. A good example is the Struts 2 devmode.
There are many Struts 2 developers familiar with the Struts 2 development mode in which more verbose logs are produced and handy resource reloading is done on a request basis to avoid restarting the server every time we change a property, validator and so on. What it is not so well known (actually it doesn’t even appear in the Struts 2 devmode page) is that it enables an OGNL injection backdoor allowing the developers to check their Value Stacks with ease and from a handy OGNL console or request parameter. This handy feature for developers turns into a security nightmare if applications are released into production with this flag on.
If we look at the Struts 2 Debugging page, we can find some info on how it works. It enables the debugging interceptor which brings us some interesting modes like “command” allowing us to evaluate any arbitrary OGNL expression passed in the “expression” parameter.
Searching around for applications with devmode enabled returns more than 140,000 sites. So, don’t forget to disable devmode before releasing your applications to production.
Keeping up to date with Struts 2 is crucial but that’s not all of it. As developers you still need to make sure that no untrusted data is passed to Struts 2 functions that evaluate their arguments as OGNL expressions. You need to ensure that your application is configured in a secure way before releasing it to production - and that’s where Fortify SCA can help.