
Vérificateur statique hors ligne qui inspecte les jars Java packagés à la recherche de versions vulnérables de netty-resolver-dns et détecte si Spring WebClient utilise réellement le résolveur DNS de Netty.
Vérificateur hors ligne pour trois CVE d'empoisonnement de cache DNS dans io.netty:netty-resolver-dns —
CVE-2026-45674, CVE-2026-47691 et CVE-2026-45673 — et pour la question à laquelle le
numéro de version ne peut pas répondre : votre application utilise-t-elle réellement ce résolveur ?
Si vous utilisez Spring WebClient, la réponse est très probablement oui, même si
netty-resolver-dns n'apparaît nulle part dans votre pom.xml et que rien dans votre code ne l'appelle.
java -jar netty-resolver-dns-check-0.1.0.jar path/to/your-app.jar
netty-resolver-dns arrive à quatre niveaux de profondeur :
spring-boot-starter-webflux
└ spring-boot-starter-reactor-netty
└ reactor-netty-http
└ reactor-netty-core
└ netty-resolver-dns (chaque lien : scope compile)
Et il n'est pas seulement présent dans le classpath. Le HttpClient de Reactor Netty — le connecteur que Spring Boot
choisit pour WebClient dès que Reactor Netty est présent — résout les noms d'hôtes avec le
DnsAddressResolverGroup de Netty, pas le résolveur du JDK :
HttpClientConfig.defaultAddressResolverGroup() → HttpResources.getOrCreateDefaultResolver()TcpResources.getOrCreateDefaultResolver() → NameResolverProvider.newNameResolverGroup(...)NameResolverProvider.newNameResolverGroup → new DnsNameResolverBuilder() → new DnsAddressResolverGroup(builder)(Idem dans reactor-netty 1.1.x, 1.2.x, 1.3.x et main.) L'ordre de détection des connecteurs de Spring Boot est
reactor > jetty > httpComponents > jdk, donc Reactor Netty l'emporte dès qu'il est présent.
Nous ne nous sommes pas arrêtés à la lecture du code source. Dans l'expérience contrôlée ci-dessous, une application Spring Boot 3.5.14 par défaut
effectuant une seule requête WebClient a envoyé une véritable requête DNS via le résolveur de Netty
(WRITE: UDP ... DefaultDnsQuestion(example.com.)).
Les avis pour CVE-2026-45674 et CVE-2026-47691 le disent clairement : « Toute application utilisant le résolveur DNS de Netty est impactée. »
Les trois CVE partagent le même correctif : 4.1.135.Final (branche 4.1) / 4.2.15.Final (branche 4.2).
Lu depuis chaque spring-boot-dependencies-<v>.pom (<netty.version>), le 2026-09-11 :
| Spring Boot | netty par défaut | |
|---|---|---|
| 3.4.0 – 3.4.13 | 4.1.115 – 4.1.130 | affecté — aucune version 3.4.x n'embarque le correctif |
| 3.5.0 – 3.5.14 | 4.1.121 – 4.1.132 | affecté |
| 3.5.15 + | 4.1.135 | corrigé |
| 4.0.0 – 4.0.6 | 4.2.7 – 4.2.12 | affecté |
| 4.0.7 + | 4.2.15 + | corrigé |
Les versions corrigées sont toutes sur Maven Central. La mise à niveau fonctionne ; cet outil ne prétend pas le contraire.
Un numéro de version, c'est une ligne de mvn dependency:tree. La question plus difficile est de savoir si le
résolveur est réellement utilisé. Nous avons donc construit quatre véritables fat jars Spring Boot 3.5.14 et un en 3.5.16,
et mesuré la vérité terrain — les requêtes DNS réellement envoyées par Netty — par rapport à ce que cet outil
déduit du jar seul :
| App | Ce qu'elle fait | Requêtes DNS Netty (exécution) | Cet outil (statique) |
|---|---|---|---|
| A | WebClient.builder() par défaut | 1 | utilisé |
| B | .resolver(DefaultAddressResolverGroup.INSTANCE) | 0 | surcharge trouvée → vérifier manuellement |
| C | spring.http.reactiveclient.connector=jdk | 0 | surcharge trouvée → vérifier manuellement |
| D | deux WebClients, un seul surchargé | 1 | surcharge trouvée → vérifier manuellement |
| E | par défaut, Spring Boot 3.5.16 | 1 (sur le 4.1.135 corrigé) | non affecté |
Le résultat honnête : l'outil dit de manière fiable « utilisé » lorsqu'il n'y a pas de surcharge, et il trouve des traces de surcharge dans votre code et votre configuration (3 sur 3, aucun faux positif sur A). Il ne peut pas distinguer B (tout surchargé) de D (un client toujours sur le défaut) — leurs preuves bytecode sont identiques. Une surcharge ne le fait donc jamais dire « non affecté » ; il dit « vérifier manuellement », et vous donne la vérification d'une minute ci-dessous.
--logging.level.io.netty.resolver.dns=DEBUGWRITE: UDP dans le journal — présent : le résolveur de Netty est utilisé ; absent : cette requête ne l'a pas utiliséNe jugez pas sur « est-ce que DnsNameResolver a été chargé ? ». L'app B a remplacé le résolveur et a quand même chargé
cette classe, car le groupe de résolveurs par défaut est construit de manière anticipée. Seules les lignes de requête sont une preuve.
java -jar netty-resolver-dns-check-0.1.0.jar <directory | jar | war>
java -jar netty-resolver-dns-check-0.1.0.jar --version-of 4.1.132.Final
Il lit ce qui est réellement empaqueté (fat jar BOOT-INF/lib, war WEB-INF/lib, jars imbriqués),
pas pom.xml — la dépendance est transitive, donc le pom vous dirait qu'elle n'est pas là.
La présence est déterminée par la classe io/netty/resolver/dns/DnsNameResolver.class, pas par les manifestes
de version. Les traces de surcharge ne sont recherchées que dans vos propres classes et application*.properties/yml
(les jars de bibliothèques référencent eux-mêmes ces classes).
La sortie est en chinois ; les lignes de verdict et les identifiants CVE sont ce sur quoi les scripts doivent se baser.
HttpClient de Reactor Netty (par exemple une passerelle) ne sont pas
analysées séparément — si Reactor Netty est présent, le chemin par défaut est supposé.API des avis GitHub, consultée le 2026-09-11 :
| CVE | GHSA | Sévérité | Affecté → corrigé |
|---|---|---|---|
| CVE-2026-45674 | GHSA-676x-f7gg-47vc | élevée 8.7 | <= 4.1.134.Final → 4.1.135.Final · 4.2.0–4.2.14 → 4.2.15.Final |
| CVE-2026-47691 | GHSA-5pvg-856g-cp85 | élevée 8.7 | idem |
| CVE-2026-45673 | GHSA-xmv7-r254-6q78 | moyenne 6.8 | idem |
La table Spring Boot se trouve dans BootTable.java ; un test unitaire redérive les trois affirmations de
la section 2 à partir de celle-ci, de sorte que la table et les affirmations ne peuvent pas diverger silencieusement.
evidence/ contient les cinq applications (A–E) et runtime.sh, qui compte les lignes WRITE: UDP par application.
tools/e2e_real_jars.py exécute cet outil contre les mêmes cinq jars et vérifie chaque verdict.
La compilation des applications nécessite Maven 3.6.3 ou plus récent.
| Code | Signification |
|---|---|
| 0 | aucune des trois CVE ne s'applique (version corrigée) |
| 1 | version affectée trouvée — y compris lorsque des traces de surcharge ont été trouvées |
| 2 | impossible à juger (aucun netty-resolver-dns trouvé, version inconnue, arguments invalides) |
| 4 | un fichier n'a pas pu être lu — « je n'ai pas pu le lire » ne doit jamais ressembler à un succès |
Apache License 2.0