skip to content
Back to GitHub.com
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events
March 3, 2021

GHSL-2020-048: Remote Code Execution in Apache Velocity - CVE-2020-13936

Alvaro Munoz

Coordinated Disclosure Timeline

Summary

Product

Apache Velocity

Tested Version

Apache Velocity 2.2

Details

Improper BlockList verification

Velocity SecureUberspector prevents access to dangerous classes and packages by checking if any methods are invoked on the blocked classes. However Velocity fails to inspect the complete class hierarchy of the object where the method is invoked. This effectively means that if a method is called on an object of a given type that extends a class or implements an interface present in the BlockList, the invocation will not be blocked. As an example, the java.lang.ClassLoader abstract class is present in the Secure Uberspector default BlockList, however, as an abstract class, it cannot be instantiated, so any calls on a ClassLoader instance will happen to be in a class extending java.lang.ClassLoader which is not present in the BlockList.

For example, given the following template, the ScriptEngineManager class will be successfully loaded:

${request.servletContext.classLoader.loadClass("javax.script.ScriptEngineManager")}

Insufficient Sandbox Protection

Even though Velocity offers a great sandbox that prevents dangerous methods from being invoked, exposing Servlet related objects (such as the Servlet context) may introduce a variaty of objects which can be used to bypass the Velocity sandbox. Deep inspection of the exposed objects’ object graph allows an attacker to get access to objects that allow them to instantiate arbitrary Java objects. According to the documentation:

The HttpServletRequest, HttpSession, ServletContext, and their attributes are automatically available in your templates.

There are different ways to access the Servlet context including:

But if the application also exposes the context tool (which is the default), the Servlet context can also be accessed through:

On a Tomcat server the Servlet context will contain the org.apache.tomcat.InstanceManager which enables an attacker to instantiate arbitrary objects. Note that the same class (regardless of its name) is available on other servlet containers such as Jetty and similar classes are available in other servers. For example JBoss/WildFly exposes org.wildfly.extension.undertow.deployment.UndertowJSPInstanceManage.

We can then try to run arbitrary Java code using a ScriptEngine:

${req.getServletContext().getAttribute('org.apache.tomcat.InstanceManager').newInstance('javax.script.ScriptEngineManager').getEngineByName('js').eval("java.lang.Runtime.getRuntime().exec('touch /tmp/pwned')")}

In addition, on Spring applications a number of other Servlet context attributes may lead to remote code execution such as:

Impact

This issue may lead to Remote Code Execution.

CVE

CVE-2020-13936

Credit

This issue was discovered and reported by GHSL team member @pwntester (Alvaro Munoz).

Contact

You can contact the GHSL team at securitylab@github.com, please include the GHSL-2020-048 in any communication regarding this issue.