
Verificador offline para Thymeleaf CVE-2026-40477 / CVE-2026-41901 — informa a qual das duas falhas SSTI com CVSS 9.0 você está exposto e se a sua linha de versão possui alguma correção (3.0.x: não possui).
Ferramenta de verificação offline para Thymeleaf CVE-2026-40477 / CVE-2026-41901 — zero dependências, um único jar, sem conexão com a internet.
Duas vulnerabilidades de bypass de SSTI com CVSS 9.0, com duas versões de correção lançadas em nove dias. Ela primeiro responde "quais delas me afetam", e depois responde à pergunta mais desconfortável:
Na minha linha de versão, existe alguma versão corrigida para a qual eu possa atualizar?
Para 3.1.x, sim (basta atualizar para 3.1.5.RELEASE).
Para 3.0.x e anteriores, não — e é justamente esse o grupo com a maior base de instalação.
O escopo afetado das duas advisories, no 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"}]}]
Ou seja, toda a linha 3.0 está incluída, e a lista versão por versão vai de 3.0.15.RELEASE até 1.0.0.
E no Maven Central, a linha 3.0 termina em 3.0.15.RELEASE, sem nenhum lançamento posterior:
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>
As versões corrigidas das duas CVEs estão na linha 3.1. Portanto, usuários de 3.0.x não têm a opção de "mudar o número da versão" —
só resta migrar entre linhas de versão principais — e 3.1 é uma mudança disruptiva listada oficialmente (trechos copiados da seção 3.1.0.M1 do 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).
Templates que usaram ${#request.…} / ${#session.…} vão falhar diretamente após a atualização; esses valores precisarão ser passados pelo Controller via Model.
Isso é uma migração que precisa ser agendada, não uma simples mudança de versão.
Contagem de dependências do deps.dev (lido diretamente em 2026-09-04, qualquer pessoa pode recalcular):
| Versão | Dependências | Quais CVEs | Pode atualizar na mesma linha? |
|---|---|---|---|
| 3.0.11.RELEASE | 1124 | Ambas | ❌ Linha 3.0 sem versão corrigida |
| 3.0.15.RELEASE | 678 | Ambas | ❌ Idem, e já é o fim da linha |
| 3.0.12.RELEASE | 641 | Ambas | ❌ |
| 3.1.3.RELEASE | 826 | Ambas | ✅ Atualizar para 3.1.5 |
| 3.1.2.RELEASE | 677 | Ambas | ✅ |
| 3.1.4.RELEASE | 70 | Apenas CVE-2026-41901 | ✅ |
| 3.1.5.RELEASE | 590 | — | Já segura |
A versão individual com a maior base de instalação é 3.0.11.RELEASE, 36% maior que a 3.1.3, a mais alta da linha 3.1, e ela não tem saída dentro da própria linha.
java -jar thymeleaf-check.jar <caminho-do-diretório-ou-jar/war> [--utf8|--gbk]
$ java -jar thymeleaf-check.jar ./target
[CRITICAL] ./target/myapp.war :: BOOT-INF/lib/thymeleaf-3.0.11.RELEASE.jar
Artefato:thymeleaf Versão 3.0.11.RELEASE (linha 3.0, fonte: MANIFEST(Implementation-Version))
Atingido por: CVE-2026-40477 + CVE-2026-41901
Afetado, e a linha 3.0 não tem nenhuma versão corrigida no Maven Central (a linha termina em 3.0.15.RELEASE).
Códigos de saída: 2 = há um artefato cuja linha de versão não tem correção na mesma linha · 1 = afetado, mas com correção na mesma linha / não foi possível determinar · 0 = nada encontrado · 3 = erro de uso ou de caminho.
Pode ser integrado diretamente ao CI.
Verifique os artefatos de build (target/*.jar, *.war), não os diretórios de código-fonte.
O Thymeleaf é, na grande maioria dos casos, introduzido de forma transitiva pelo spring-boot-starter-thymeleaf, e o starter não define versão —
a versão do Thymeleaf simplesmente não aparece no pom. Nesse caso, a ferramenta dirá explicitamente "não foi possível determinar pelo pom", em vez de tratá-lo como inexistente.
Três critérios de identificação, ordenados por confiabilidade:
Implementation-Version do MANIFEST — reconhece o jar mesmo se ele foi renomeado por ferramentas de repacotamento.
(O jar oficial do Thymeleaf tem apenas MANIFEST.MF em META-INF/, sem diretório maven/, então este é o critério mais forte para ele.)pom.propertiesOs diretórios BOOT-INF/lib/ e WEB-INF/lib/ dentro de fat jars / wars são desmembrados e examinados um a um, e o MANIFEST de jars embutidos também é lido.
CVE-2026-40477 | CVE-2026-41901 | |
|---|---|---|
| GHSA | GHSA-r4v4-5mwr-2fwr | GHSA-c9ph-gxww-7744 |
| CVSS | 9.0 | 9.0 |
| Afetado | <= 3.1.3.RELEASE | <= 3.1.4.RELEASE |
| Correção | 3.1.4.RELEASE | 3.1.5.RELEASE |
| Divulgação | 2026-04-15 | 2026-05-04 |
| Texto oficial | "fails to properly restrict the scope of accessible objects" | "fails to properly neutralize specific constructs", ocorre em contexto sandboxed (restricted) |
O escopo afetado da segunda inclui a 3.1.4, então quem atualizou para 3.1.4 seguindo a primeira advisory cai dentro da segunda.
Mas não leia isso como "a correção oficial não foi completa" — as duas advisories descrevem mecanismos diferentes,
e as versões oficiais 3.1.4 (2026-04-12) e 3.1.5 (2026-04-21) têm nove dias de diferença,
sem nenhum texto oficial dizendo que a correção anterior era incompleta. Esta ferramenta apenas apresenta os fatos lado a lado, sem tirar essa conclusão por você.
Cada número em RuleTable.java pode ser verificado retroativamente:
python tools/gen_rules.py --show
Ele cruza a tabela de verificação com duas fontes primárias — os intervalos afetados e a lista versão por versão do OSV, e o
maven-metadata.xml do Maven Central — e, se houver divergência, sai com código de saída diferente de zero.
Três convenções:
mvn package # JDK 17;target/thymeleaf-check-0.1.0.jar
mvn test # 19 casos de teste
A ausência de dependências em tempo de execução é intencional: uma ferramenta de verificação precisa poder ser jogada em qualquer ambiente e executada diretamente.
Apache-2.0