
[CVE-2022-22980] Inyección de expresiones SpEL en Spring Data MongoDB
[CVE-2022-22980] Inyección de Expresión SpEL en Spring Data MongoDB
MongoDB es una base de datos NoSQL orientada a documentos, con la escalabilidad y flexibilidad que se utiliza para el almacenamiento de grandes volúmenes de datos. En lugar de usar tablas y filas como en las bases de datos relacionales tradicionales, MongoDB utiliza colecciones y documentos. Los documentos consisten en pares clave-valor, que son la unidad básica de datos en MongoDB.
Spring Data for MongoDB es parte del proyecto general Spring Data, cuyo objetivo es proporcionar un modelo de programación basado en Spring, familiar y coherente, para nuevos almacenes de datos, manteniendo al mismo tiempo las características y capacidades específicas de cada almacén. El proyecto Spring Data MongoDB proporciona integración con la base de datos documental MongoDB. Las áreas funcionales clave de Spring Data MongoDB son un modelo centrado en POJO para interactuar con una DBCollection de MongoDB y escribir fácilmente una capa de acceso a datos de estilo Repository.
El 20 de junio de 2022, VMware publicó un aviso de seguridad en su sitio web oficial relacionado con la vulnerabilidad de inyección de expresiones SpEL (que conduce a la ejecución remota de código) que afecta a Spring Data MongoDB. Puede encontrar información detallada sobre la vulnerabilidad CVE-2022-22980 a continuación.
Vulnerabilidad
Una aplicación de Spring Data MongoDB es vulnerable a la inyección SpEL cuando utiliza métodos de consulta anotados con @Query o @Aggregation con expresiones SpEL que contienen marcadores de posición de parámetros de consulta para el enlace de valores, si la entrada no está saneada. Alternativamente, las configuraciones que exponen métodos de consulta de repositorio sin involucrar código de aplicación adicional (como Spring Data REST) también son vulnerables.
Específicamente, una aplicación es vulnerable cuando se cumplen todas las siguientes condiciones:
@Query o @Aggregation que hacen uso de SpEL (Spring Expression Language) y utilizan referencias a parámetros de entrada (?0, ?1, …) dentro de la expresión SpELUna aplicación no es vulnerable si se cumple cualquiera de las siguientes condiciones:
QueryMethodEvaluationContextProvider que limita el uso de SpELVersiones Afectadas
Spring Data MongoDB 3.4.0, 3.3.0 a 3.3.4, y versiones anteriores están afectadas por la vulnerabilidad CVE-2022-22980 Spring Data MongoDB SpEL Expression Injection.
Estado
Se han publicado Spring Data MongoDB 3.4.1 y 3.3.5, que contienen las correcciones.
Mitigación y Soluciones Alternativas Sugeridas
La respuesta preferida es actualizar a Spring Data MongoDB 3.4.1 y 3.3.5 o superior. Si ya lo ha hecho, no son necesarias soluciones alternativas. Sin embargo, algunos pueden encontrarse en una situación en la que actualizar sea imposible rápidamente. Por esa razón, el equipo de Spring ha proporcionado algunas soluciones alternativas a continuación.
Uso de la sintaxis de arrays: si la aplicación requiere expresiones SpEL dinámicas controladas por la entrada del usuario, entonces reescriba las declaraciones de consulta o agregación para usar referencias a parámetros ([0] en lugar de ?0) dentro de la expresiónImplementación de un método de repositorio personalizado: Reemplazar la expresión SpEL con una implementación de método de repositorio personalizado es una solución alternativa viable para ensamblar su consulta dinámica dentro del código de la aplicación. Consulte la documentación de referencia sobre personalización de repositorios para obtener más detalles.Análisis del Parche: Problema de GitHub y Commits Relacionados
El problema de GitHub para la vulnerabilidad de inyección SpEL es accesible desde github.com/spring-projects/spring-data-mongodb/issues/4089.
Con la ayuda de los dos commits siguientes, la vulnerabilidad relacionada ha sido corregida.
Con estos commits, se ha añadido la clase spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java.
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()));