
[CVE-2022-22980] Spring Data MongoDB SpEL Expression Injection
[CVE-2022-22980] Spring Data MongoDB SpEL Expression Injection
MongoDB is a document-oriented NoSQL database with the scalable and flexible that used for high volume data storage. Instead of using tables and rows as in the traditional relational databases, MongoDB makes use of collections and documents. Documents consist of key-value pairs which are the basic unit of data in MongoDB.
Spring Data for MongoDB is part of the umbrella Spring Data project which aims to provide a familiar and consistent Spring-based programming model for new datastores while retaining store-specific features and capabilities. The Spring Data MongoDB project provides integration with the MongoDB document database. Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB DBCollection and easily writing a Repository style data access layer.
On 20th June 2022, VMware released a security advisory on its official website that related to SpEL Expression Injection (leads to remote code execution) vulnerability affecting Spring Data MongoDB. You can find detailed information about the CVE-2022-22980 vulnerability in the down below.
Vulnerability
A Spring Data MongoDB application is vulnerable to SpEL Injection when using @Query or @Aggregation annotated query methods with SpEL expressions that contain query parameter placeholders for value binding if the input is not sanitized. Alternatively, arrangements that expose repository query methods without involving additional application code (such as Spring Data REST) are vulnerable as well.
Specifically, an application is vulnerable when all of the following are true:
@Query or @Aggregation that make use of SpEL (Spring Expression Language) and use input parameter references (?0, ?1, …) within the SpEL expressionAn application is not vulnerable if any of the following is true:
QueryMethodEvaluationContextProvider that limits SpEL usageAffected Versions
Spring Data MongoDB 3.4.0, 3.3.0 to 3.3.4, and older versions are affected by CVE-2022-22980 Spring Data MongoDB SpEL Expression Injection vulnerability.
Status
Spring Data MongoDB 3.4.1 and 3.3.5, which contain the fixes, have been released.
Mitigation and Suggested Workarounds
The preferred response is to update to Spring Data MongoDB 3.4.1 and 3.3.5 or greater. If you have done this, then no workarounds are necessary. However, some may be in a position where upgrading is impossible to do quickly. For that reason, Spring team have provided some workarounds below.
Using array syntax: if the application requires dynamic SpEL expressions that are controlled by user input, then rewrite query or aggregation declarations to use parameter references ([0] instead of ?0) within the expressionImplementing a custom repository method: Replacing the SpEL expression with a custom repository method implementation is a viable workaround to assemble your dynamic query within the application code. Refer to the reference documentation on repository customization for further details.Patch Analysis: GitHub Issue and Related Commits
GitHub issue for SpEL injection vulnerability can be accessible from github.com/spring-projects/spring-data-mongodb/issues/4089.
With the help of the two commit in below, related vulnerability has been fixed.
With these commits spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java class has been added.
class EvaluationContextExpressionEvaluator implements SpELExpressionEvaluator {
ValueProvider valueProvider;
ExpressionParser expressionParser;
Supplier<EvaluationContext> evaluationContext;
public EvaluationContextExpressionEvaluator(ValueProvider valueProvider, ExpressionParser expressionParser,
Supplier<EvaluationContext> evaluationContext) {
this.valueProvider = valueProvider;
this.expressionParser = expressionParser;
this.evaluationContext = evaluationContext;
}
@Nullable
@Override
public <T> T evaluate(String expression) {
return evaluateExpression(expression, Collections.emptyMap());
}
public EvaluationContext getEvaluationContext(String expressionString) {
return evaluationContext != null ? evaluationContext.get() : new StandardEvaluationContext();
}
public SpelExpression getParsedExpression(String expressionString) {
return (SpelExpression) (expressionParser != null ? expressionParser : new SpelExpressionParser())
.parseExpression(expressionString);
}
public <T> T evaluateExpression(String expressionString, Map<String, Object> variables) {
SpelExpression expression = getParsedExpression(expressionString);
EvaluationContext ctx = getEvaluationContext(expressionString);
variables.entrySet().forEach(entry -> ctx.setVariable(entry.getKey(), entry.getValue()));
Object result = expression.getValue(ctx, Object.class);
return (T) result;
}
}

spring-projects/spring-data-mongodb/blob/main/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingContext.java class has also been modified as follow:
