
Comprobador offline para Thymeleaf CVE-2026-40477 / CVE-2026-41901: te indica a cuál de las dos vulnerabilidades SSTI con CVSS 9.0 estás expuesto y si tu línea de versión tiene alguna corrección (3.0.x: no la tiene).
Herramienta de verificación offline para Thymeleaf CVE-2026-40477 / CVE-2026-41901 — cero dependencias, un solo jar, sin conexión.
Dos bypass de SSTI con CVSS 9.0, dos versiones de parche publicadas en nueve días. Primero responde «¿cuáles me afectan?», y luego responde a esa pregunta más incómoda:
En mi línea de versiones, ¿hay alguna versión parcheada a la que pueda subir?
Para 3.1.x, sí (basta con subir a 3.1.5.RELEASE).
Para 3.0.x y anteriores, no — y ese es precisamente el grupo con mayor base instalada.
El rango afectado de ambos advisories en OSV es 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"}]}]
Es decir, toda la línea 3.0 está afectada, y en la lista versión por versión aparecen desde 3.0.15.RELEASE hasta 1.0.0.
Y en Maven Central la línea 3.0 termina en 3.0.15.RELEASE, sin publicaciones posteriores:
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>
Las versiones parcheadas de ambos CVE están en la línea 3.1. Así que los usuarios de 3.0.x no tienen la opción de «cambiar el número de versión»;
solo les queda migrar entre líneas de versión mayores — y 3.1 es un cambio disruptivo declarado oficialmente (copiado punto por punto de la sección 3.1.0.M1 del ChangeLog.txt oficial):
- 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).
Las plantillas que hayan usado ${#request.…} / ${#session.…} fallarán directamente al subir; esos valores deberán pasar a través del Controller al Model.
Esto es una migración que requiere planificación, no un simple cambio de versión.
Conteo de dependencias de deps.dev (leído directamente el 2026-09-04, cualquiera puede recalcularlo):
| Versión | Dependencias | ¿Cuáles le afectan? | ¿Puede subir dentro de la misma línea? |
|---|---|---|---|
| 3.0.11.RELEASE | 1124 | Ambas | ❌ La línea 3.0 no tiene versión parcheada |
| 3.0.15.RELEASE | 678 | Ambas | ❌ Igual que arriba, y además es el final de esa línea |
| 3.0.12.RELEASE | 641 | Ambas | ❌ |
| 3.1.3.RELEASE | 826 | Ambas | ✅ Subir a 3.1.5 |
| 3.1.2.RELEASE | 677 | Ambas | ✅ |
| 3.1.4.RELEASE | 70 | Solo CVE-2026-41901 | ✅ |
| 3.1.5.RELEASE | 590 | — | Ya seguro |
La versión individual con mayor base instalada es 3.0.11.RELEASE, un 36 % más que la más alta de la línea 3.1 (3.1.3), y no tiene salida dentro de su misma línea.
java -jar thymeleaf-check.jar <directorio o ruta a jar/war> [--utf8|--gbk]
$ java -jar thymeleaf-check.jar ./target
[CRITICAL] ./target/myapp.war :: BOOT-INF/lib/thymeleaf-3.0.11.RELEASE.jar
Artefacto:thymeleaf Versión 3.0.11.RELEASE (línea 3.0, según: MANIFEST(Implementation-Version))
Afectado por: CVE-2026-40477 + CVE-2026-41901
Afectado, y la línea 3.0 no tiene ninguna versión parcheada en Maven Central (esa línea termina en 3.0.15.RELEASE).
Códigos de salida: 2 = hay un artefacto cuya línea de versión no tiene parche dentro de la misma línea · 1 = afectado pero se puede subir dentro de la misma línea / no se puede determinar · 0 = no se encontró nada · 3 = error de uso o de ruta.
Se puede integrar directamente en CI.
Escanee los artefactos de build (target/*.jar, *.war), no los directorios de código fuente.
Thymeleaf se introduce en la gran mayoría de los casos de forma transitiva a través de spring-boot-starter-thymeleaf, y el starter no incluye la versión —
en el pom no se ve la versión de Thymeleaf. En ese caso la herramienta indicará claramente «no se puede determinar desde el pom», en lugar de tratarlo como inexistente.
Tres criterios de identificación, ordenados por fiabilidad:
Implementation-Version del MANIFEST — reconoce el jar incluso si una herramienta de reempaquetado le cambió el nombre.
(El jar oficial de Thymeleaf en META-INF/ solo tiene MANIFEST.MF, sin directorio maven/, por lo que para él este es el criterio más sólido.)pom.propertiesLos BOOT-INF/lib/ y WEB-INF/lib/ dentro de fat jars / wars se desglosan y examinan uno a uno; también se lee el MANIFEST de los jars embebidos.
CVE-2026-40477 | CVE-2026-41901 | |
|---|---|---|
| GHSA | GHSA-r4v4-5mwr-2fwr | GHSA-c9ph-gxww-7744 |
| CVSS | 9.0 | 9.0 |
| Afectados | <= 3.1.3.RELEASE | <= 3.1.4.RELEASE |
| Parche | 3.1.4.RELEASE | 3.1.5.RELEASE |
| Divulgación | 2026-04-15 | 2026-05-04 |
| Texto oficial | "fails to properly restrict the scope of accessible objects" | "fails to properly neutralize specific constructs", ocurre en un contexto sandboxed (restringido) |
El rango afectado del segundo incluye 3.1.4, así que quienes subieron a 3.1.4 siguiendo el primer advisory quedan dentro del segundo.
Pero no lo lea como «el parche oficial no se hizo bien» — los dos advisories describen mecanismos distintos;
las versiones oficiales 3.1.4 (2026-04-12) y 3.1.5 (2026-04-21) están separadas por nueve días,
y ningún texto oficial afirma que el primer parche fuera incompleto. Esta herramienta solo presenta los hechos en paralelo, no saca esa conclusión por usted.
Cada número en RuleTable.java se puede contrastar:
python tools/gen_rules.py --show
Contrasta la tabla de decisión con dos fuentes primarias — los rangos afectados y la lista versión por versión de OSV, y el
maven-metadata.xml de Maven Central — y si no coinciden, sale con código distinto de cero.
Tres convenciones:
mvn package # JDK 17;target/thymeleaf-check-0.1.0.jar
mvn test # 19 casos de prueba
La ausencia de dependencias en tiempo de ejecución es intencionada: una herramienta de verificación debe poder ejecutarse directamente en cualquier entorno.
Apache-2.0