Summary
A user with privileges to edit a FreeMarker template (e.g. a Component) may execute arbitrary Java code or run arbitrary system commands with the same privileges as the account running Lithium CMS.
Product
Lithium CMS
Tested Version
Latest
Details
Server-Side Template Injection
Even though Lithium CMS does a good job limiting what objects are available to FreeMarker templates and always wraps them with TemplateModel
s, it is still possible to bypass the FreeMarker 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. In particular:
${http.class.protectionDomain.classLoader}
Will return an instance of sun.misc.Launcher$AppClassLoader
. Having access to a ClassLoader we can load arbitrary classes since FreeMarker list of unsafe methods does not disallow ClassLoader.loadClass()
. However, FreeMarker’s deny list does disallow invoking newInstance()
on both java.lang.Class
and java.lang.reflect.Constructor
, so there is no way for an attacker to instantiate arbitrary objects.
Even though FreeMarker also disallows setter methods on java.lang.reflect.Field
, it does not forbid getter ones. We can use this gap in the blocklist to get public
, static
fields from any class which can be used to instantiate arbitrary objects.
Impact
This issue leads to Remote Code Execution
.
Coordinated Disclosure Timeline
This report was subject to the GHSL coordinated disclosure policy.
- 04/15/2020: Report sent to vendor
- 05/13/2020: Issue is fixed on all production systems (version 20.5)
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 a reference to GHSL-2020-071
in any communication regarding this issue.