
Checker offline per CVE-2026-40477 / CVE-2026-41901 di Thymeleaf — ti dice a quale delle due vulnerabilità SSTI con CVSS 9.0 sei esposto e se la tua linea di versione dispone di una correzione (3.0.x: non la ha).
Strumento di verifica offline per Thymeleaf CVE-2026-40477 / CVE-2026-41901 — zero dipendenze, singolo jar, nessuna connessione di rete.
Due bypass SSTI con CVSS 9.0, due versioni di fix pubblicate a nove giorni di distanza. Prima risponde a «quali di queste mi colpiscono», poi risponde alla domanda più scomoda:
Sulla mia linea di versione, esiste una versione di fix a cui posso aggiornare?
Per 3.1.x, sì (basta aggiornare a 3.1.5.RELEASE).
Per 3.0.x e versioni precedenti, no — e proprio quella è la fascia con la base installata più ampia.
L'intervallo di versioni affette delle due advisory, in OSV, è introduced: 0:
curl -s https://api.osv.dev/v1/vulns/GHSA-r4v4-5mwr-2fwr | jq '.affected[0].ranges'
# [{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.4.RELEASE"}]}]
Ciò significa che l'intera linea 3.0 è inclusa, e nell'elenco versione per versione figurano dalla 3.0.15.RELEASE fino alla 1.0.0.
E su Maven Central la linea 3.0 termina con 3.0.15.RELEASE, senza ulteriori rilasci successivi:
curl -s https://repo1.maven.org/maven2/org/thymeleaf/thymeleaf/maven-metadata.xml \
| grep -o '<version>3\.0\.[^<]*</version>' | tail -1
# <version>3.0.15.RELEASE</version>
Le versioni di fix di entrambe le CVE si trovano sulla linea 3.1. Quindi gli utenti 3.0.x non hanno l'opzione «cambia il numero di versione»,
ma solo la migrazione attraverso un cambio di linea maggiore — e 3.1 è elencato ufficialmente come modifica di rottura (trascritta punto per punto dalla sezione 3.1.0.M1 del ChangeLog.txt ufficiale):
- Removed web-API based expression security objects (#request, #response, #session, #servletContext).
- Removed support for Spring 3.x and Spring 4.x.
- Set minimum JDK compatibility level to JDK 8 project-wide (JDK 17 for thymeleaf-spring6).
I template che hanno scritto ${#request.…} / ${#session.…} andranno direttamente in errore dopo l'aggiornamento; questi valori dovranno essere passati dal Controller tramite il Model.
Questa è una migrazione da pianificare, non un semplice cambio di numero di versione.
Conteggio dipendenze da deps.dev (letto direttamente il 2026-09-04, chiunque può ricalcolarlo):
| Versione | Dipendenze | Quali CVE | Aggiornabile sulla stessa linea |
|---|---|---|---|
| 3.0.11.RELEASE | 1124 | Entrambe | ❌ Nessuna fix sulla linea 3.0 |
| 3.0.15.RELEASE | 678 | Entrambe | ❌ Come sopra, ed è già il capolinea della linea |
| 3.0.12.RELEASE | 641 | Entrambe | ❌ |
| 3.1.3.RELEASE | 826 | Entrambe | ✅ Aggiorna a 3.1.5 |
| 3.1.2.RELEASE | 677 | Entrambe | ✅ |
| 3.1.4.RELEASE | 70 | Solo CVE-2026-41901 | ✅ |
| 3.1.5.RELEASE | 590 | — | Già sicura |
La singola versione con la base installata più ampia è 3.0.11.RELEASE, superiore del 36% rispetto alla più alta della linea 3.1, la 3.1.3 — e non ha una via d'uscita sulla stessa linea.
java -jar thymeleaf-check.jar <percorso directory o jar/war> [--utf8|--gbk]
$ java -jar thymeleaf-check.jar ./target
[CRITICAL] ./target/myapp.war :: BOOT-INF/lib/thymeleaf-3.0.11.RELEASE.jar
Artefatto:thymeleaf Versione 3.0.11.RELEASE (linea 3.0, fonte: MANIFEST(Implementation-Version))
Colpito da: CVE-2026-40477 + CVE-2026-41901
Affetto, e la linea 3.0 non ha alcuna versione di fix su Maven Central (la linea termina con 3.0.15.RELEASE).
Codice di uscita: 2 = un artefatto si trova su una linea di versione senza fix sulla stessa linea · 1 = affetto ma aggiornabile sulla stessa linea / non determinabile · 0 = nessuna rilevazione · 3 = errore di utilizzo o percorso.
Può essere integrato direttamente nella CI.
Scansiona gli artefatti di build (target/*.jar, *.war), non le directory del codice sorgente.
Thymeleaf nella stragrande maggioranza dei casi viene introdotto transitivamente da spring-boot-starter-thymeleaf, e lo starter non porta con sé la versione —
nel pom non si vede affatto il numero di versione di Thymeleaf. In quel caso lo strumento dichiara esplicitamente «non determinabile dal pom», invece di trattarlo come inesistente.
Tre criteri di identificazione, ordinati per affidabilità:
Implementation-Version nel MANIFEST — riconosce il jar anche se rinominato da strumenti di repackaging.
(Il jar ufficiale di Thymeleaf in META-INF/ contiene solo MANIFEST.MF, senza directory maven/, quindi per esso questo è il criterio più solido.)pom.propertiesLe directory BOOT-INF/lib/ e WEB-INF/lib/ dentro fat jar / war vengono scomposte ed esaminate una per una, leggendo anche il MANIFEST dei jar incorporati.
CVE-2026-40477 | CVE-2026-41901 | |
|---|---|---|
| GHSA | GHSA-r4v4-5mwr-2fwr | GHSA-c9ph-gxww-7744 |
| CVSS | 9.0 | 9.0 |
| Affette | <= 3.1.3.RELEASE | <= 3.1.4.RELEASE |
| Fix | 3.1.4.RELEASE | 3.1.5.RELEASE |
| Divulgazione | 2026-04-15 | 2026-05-04 |
| Testo ufficiale | "fails to properly restrict the scope of accessible objects" | "fails to properly neutralize specific constructs", si verifica nel contesto sandboxed (restricted) |
L'intervallo affetto della seconda include la 3.1.4, quindi chi è passato alla 3.1.4 seguendo la prima advisory ricade nella seconda.
Ma non va letta come «la fix ufficiale non era completa» — le due advisory descrivono meccanismi diversi;
le due versioni ufficiali 3.1.4 (2026-04-12) e 3.1.5 (2026-04-21) distano nove giorni,
e nessun testo ufficiale afferma che il primo fix fosse incompleto. Questo strumento si limita a esporre i fatti affiancati, senza trarre la conclusione al posto tuo.
Ogni numero in RuleTable.java è riconducibile e verificabile:
python tools/gen_rules.py --show
Confronta la tabella di valutazione con due fonti primarie — gli intervalli affetti e l'elenco versione per versione di OSV, e il
maven-metadata.xml di Maven Central — ed esce con codice non zero se non corrispondono.
Tre convenzioni:
mvn package # JDK 17;target/thymeleaf-check-0.1.0.jar
mvn test # 19 casi di test
L'assenza di dipendenze a runtime è intenzionale: uno strumento di verifica deve poter essere lanciato in qualsiasi ambiente senza preparazione.
Apache-2.0