
[CVE-2022-22980] Injection d'expression SpEL Spring Data MongoDB
[CVE-2022-22980] Injection d'expression SpEL dans Spring Data MongoDB
MongoDB est une base de données NoSQL orientée documents, scalable et flexible, utilisée pour le stockage de données à volume élevé. Au lieu d'utiliser des tables et des lignes comme dans les bases de données relationnelles traditionnelles, MongoDB utilise des collections et des documents. Les documents sont constitués de paires clé-valeur, qui sont l'unité de base des données dans MongoDB.
Spring Data for MongoDB fait partie du projet parapluie Spring Data, qui vise à fournir un modèle de programmation familier et cohérent basé sur Spring pour les nouveaux magasins de données tout en conservant les fonctionnalités et capacités spécifiques au magasin. Le projet Spring Data MongoDB fournit une intégration avec la base de données documentaire MongoDB. Les principaux domaines fonctionnels de Spring Data MongoDB sont un modèle centré sur les POJO pour interagir avec une DBCollection MongoDB et écrire facilement une couche d'accès aux données de type Repository.
Le 20 juin 2022, VMware a publié un avis de sécurité sur son site officiel concernant une vulnérabilité d'injection d'expression SpEL (menant à une exécution de code à distance) affectant Spring Data MongoDB. Vous trouverez des informations détaillées sur la vulnérabilité CVE-2022-22980 ci-dessous.
Vulnérabilité
Une application Spring Data MongoDB est vulnérable à l'injection SpEL lorsqu'elle utilise des méthodes de requête annotées avec @Query ou @Aggregation avec des expressions SpEL contenant des espaces réservés de paramètres de requête pour la liaison de valeurs si l'entrée n'est pas assainie. De plus, les configurations qui exposent des méthodes de requête de référentiel sans impliquer de code applicatif supplémentaire (comme Spring Data REST) sont également vulnérables.
Plus précisément, une application est vulnérable lorsque toutes les conditions suivantes sont réunies :
@Query ou @Aggregation qui utilisent SpEL (Spring Expression Language) et utilisent des références de paramètres d'entrée (?0, ?1, …) dans l'expression SpELUne application n'est pas vulnérable si l'une des conditions suivantes est vraie :
QueryMethodEvaluationContextProvider qui limite l'utilisation de SpELVersions affectées
Spring Data MongoDB 3.4.0, 3.3.0 à 3.3.4, et les versions antérieures sont affectées par la vulnérabilité CVE-2022-22980 Spring Data MongoDB SpEL Expression Injection.
Statut
Spring Data MongoDB 3.4.1 et 3.3.5, qui contiennent les correctifs, ont été publiés.
Atténuation et solutions de contournement suggérées
La réponse préférée est de mettre à jour vers Spring Data MongoDB 3.4.1 et 3.3.5 ou une version ultérieure. Si vous avez fait cela, aucune solution de contournement n'est nécessaire. Cependant, certains peuvent être dans une position où la mise à niveau est impossible à faire rapidement. Pour cette raison, l'équipe Spring a fourni quelques solutions de contournement ci-dessous.
Utiliser la syntaxe de tableau : si l'application nécessite des expressions SpEL dynamiques contrôlées par l'entrée utilisateur, alors réécrivez les déclarations de requête ou d'agrégation pour utiliser des références de paramètres ([0] au lieu de ?0) dans l'expression.Implémenter une méthode de référentiel personnalisée : Remplacer l'expression SpEL par une implémentation de méthode de référentiel personnalisée est une solution de contournement viable pour assembler votre requête dynamique dans le code de l'application. Référez-vous à la documentation de référence sur la personnalisation du référentiel pour plus de détails.Analyse du correctif : Problème GitHub et commits associés
Le problème GitHub pour la vulnérabilité d'injection SpEL est accessible depuis github.com/spring-projects/spring-data-mongodb/issues/4089.
Grâce aux deux commits ci-dessous, la vulnérabilité associée a été corrigée.
Avec ces commits, la classe spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/EvaluationContextExpressionEvaluator.java a été ajoutée.
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()));