Summary
A Server-Side Template Injection was identified in Dropwizard self-validating feature enabling attackers to inject arbitrary Java EL expressions, leading to Remote Code Execution (RCE) vulnerability.
CVE
- CVE-2020-5245
- CVE-2020-11002
Product
DropWizard
Tested Version
v2.0.1
Details
DropWizard self-validating classes use Java Bean Validation (JSR 380) custom constraint validators. When building custom constraint violation error messages, it is important to understand that they support different types of interpolation, including Java EL expressions. Therefore if an attacker can inject arbitrary data in the error message template being passed to ConstraintValidatorContext.buildConstraintViolationWithTemplate()
argument, he will be able to run arbitrary Java code. Unfortunately, it is common that validated (and therefore, normally untrusted) bean properties flow into the custom error message.
DropWizard’s io.dropwizard.validation.selfvalidating.ViolationCollector.addViolation()
passes its argument into ConstraintValidatorContext.buildConstraintViolationWithTemplate()
without any further sanitization. Therefore, any untrusted data being passed to addViolation()
will be evaluated as an EL expression allowing arbitrary code execution.
Note that this is not a vulnerability in the framework per-se, but an RCE vulnerable API being exposed to developers without proper information. We don’t think this is only a missing warning in the documentation, but rather we think that this API should protect developers against potential misuse (see recommendations to disable EL interpolation altogether below).
As a proof of concept you can reuse dropwizard-example
project and modify Person.java
to become self-validated:
...
import io.dropwizard.validation.selfvalidating.SelfValidating;
import io.dropwizard.validation.selfvalidating.SelfValidation;
import io.dropwizard.validation.selfvalidating.ViolationCollector;
@SelfValidating
public class Person {
...
@SelfValidation
public void validateFullName(ViolationCollector col) {
if (fullName.contains("$")) {
col.addViolation("Full name contains invalid characters: " + fullName);
}
}
...
Note that a property of the validated, and therefore normally untrusted, bean is passed to addViolation()
which in turn will pass it to ConstraintValidatorContext.buildConstraintViolationWithTemplate(0)
.
To reproduce the issue, send a POST request to http://server/people
with the following body:
{"fullName":"java.lang.Runtime.getRuntime().exec('touch /tmp/pwned');//${''.class.forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('js').eval(validatedValue.fullName)}","jobTitle":"Title"}
We can see the process has been executed by checking the existence of /tmp/pwned
file in conductor file system or simply by inspecting the response
Impact
This issue may lead to Remote Code execution
Remediation
There are different approaches to remediate the issue:
- Do not include validated bean properties in the custom error message.
- Sanitize the validated bean properties to make sure that there are no EL expressions. An example of valid sanitization logic can be found here.
- Disable the EL interpolation and only use
ParameterMessageInterpolator
:Validator validator = Validation.byDefaultProvider() .configure() .messageInterpolator( new ParameterMessageInterpolator() ) .buildValidatorFactory() .getValidator();
- Replace Hibernate-Validator with Apache BVal which in its latest version does not interpolate EL expressions by default. Note that this replacement may not be a simple drop-in replacement.
Coordinated Disclosure Timeline
- 02/19/2020: Report sent to Vendor
- 03/12/2020: Sent email to
dropwizard.committers+security@gmail.com
to ask for confirmation and acknowledge of the report - 02/24/2020: Advisory was published
- 03/12/2020: Sent an email to Dropwizard letting them know the fix is insufficient due to hibernate implementation bug
- 03/26/2020: New fix is ready for testing
Vendor Advisories
Credit
This issue was discovered and reported by GHSL team member @pwntester (Alvaro Muñoz). We would like to thank Guillaume Smet from the Hibernate Validator team for help with the remediation advice.
Contact
You can contact the GHSL team at securitylab@github.com
, please include the GHSL-2020-030
in any communication regarding this issue.