
[CVE-2022-22980] Spring Data MongoDB SpEL Expression Injection
[CVE-2022-22980] Spring Data MongoDB SpEL Expression Injection
MongoDB è un database NoSQL orientato ai documenti, scalabile e flessibile, utilizzato per l'archiviazione di grandi volumi di dati. Invece di usare tabelle e righe come nei tradizionali database relazionali, MongoDB utilizza collezioni e documenti. I documenti sono composti da coppie chiave-valore, che costituiscono l'unità di base dei dati in MongoDB.
Spring Data for MongoDB fa parte del progetto ombrello Spring Data, che mira a fornire un modello di programmazione familiare e coerente basato su Spring per nuovi datastore, mantenendo al contempo le caratteristiche e le capacità specifiche del datastore. Il progetto Spring Data MongoDB fornisce l'integrazione con il database documentale MongoDB. Le aree funzionali chiave di Spring Data MongoDB sono un modello incentrato sui POJO per interagire con una DBCollection di MongoDB e la facile scrittura di un livello di accesso ai dati in stile Repository.
Il 20 giugno 2022, VMware ha pubblicato un avviso di sicurezza sul suo sito ufficiale relativo alla vulnerabilità di SpEL Expression Injection (che porta all'esecuzione remota di codice) che colpisce Spring Data MongoDB. Puoi trovare informazioni dettagliate sulla vulnerabilità CVE-2022-22980 qui sotto.
Vulnerabilità
Un'applicazione Spring Data MongoDB è vulnerabile alla SpEL Injection quando utilizza metodi di query annotati con @Query o @Aggregation con espressioni SpEL che contengono segnaposto di parametri per il binding dei valori, se l'input non è sanificato. In alternativa, anche le configurazioni che espongono metodi di query del repository senza coinvolgere codice applicativo aggiuntivo (come Spring Data REST) sono vulnerabili.
Nello specifico, un'applicazione è vulnerabile quando sono vere tutte le seguenti condizioni:
@Query o @Aggregation che utilizzano SpEL (Spring Expression Language) e usano riferimenti a parametri di input (?0, ?1, …) all'interno dell'espressione SpELUn'applicazione non è vulnerabile se è vera una qualsiasi delle seguenti condizioni:
QueryMethodEvaluationContextProvider che limita l'uso di SpELVersioni Affette
Spring Data MongoDB 3.4.0, da 3.3.0 a 3.3.4, e versioni precedenti sono affette dalla vulnerabilità CVE-2022-22980 Spring Data MongoDB SpEL Expression Injection.
Stato
Sono state rilasciate Spring Data MongoDB 3.4.1 e 3.3.5, che contengono le correzioni.
Mitigazione e Workaround Suggeriti
La risposta preferita è aggiornare a Spring Data MongoDB 3.4.1 e 3.3.5 o successive. Se lo hai fatto, non sono necessari workaround. Tuttavia, alcuni potrebbero trovarsi in una posizione in cui l'aggiornamento è impossibile da fare rapidamente. Per questo motivo, il team di Spring ha fornito alcuni workaround qui sotto.
Utilizzo della sintassi array: se l'applicazione richiede espressioni SpEL dinamiche controllate dall'input utente, riscrivi le dichiarazioni di query o aggregazione per utilizzare riferimenti a parametri ([0] invece di ?0) all'interno dell'espressioneImplementazione di un metodo repository personalizzato: Sostituire l'espressione SpEL con un'implementazione di metodo repository personalizzato è un workaround valido per assemblare la query dinamica all'interno del codice applicativo. Fare riferimento alla documentazione di riferimento sulla personalizzazione del repository per ulteriori dettagli.Analisi della Patch: Issue GitHub e Commit Correlati
L'issue GitHub per la vulnerabilità SpEL injection è accessibile da github.com/spring-projects/spring-data-mongodb/issues/4089.
Con l'aiuto dei due commit qui sotto, la vulnerabilità correlata è stata risolta.
Con questi commit è stata aggiunta la classe 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()));
Object result = expression.getValue(ctx, Object.class);
return (T) result;
}
}
