Principaux enseignements
- Les outils de compilation génèrent des risques pour la production, même lorsqu'ils ne sont jamais déployés en tant que code d'exécution de l'application.
- Webpack ne publie pas de branches LTS, et les corrections sont intégrées à la branche 5.x active plutôt qu’aux anciennes versions mineures.
- Le code exécuté lors de la compilation s'exécute avec les sources, les identifiants et les jetons auxquels le processus de compilation a accès.
- Recompiler avec le même Webpack vulnérable ne change rien, car la faille est réémise à chaque fois.
La plupart des programmes de détection des vulnérabilités excluent discrètement la chaîne de compilation. Celle-ci se trouve dans les `devDependencies`, ne s'exécute jamais sur un hôte de production, et lorsqu'elle apparaît dans un rapport d'analyse, elle ne suscite qu'un haussement d'épaules et se retrouve reléguée tout en bas de la liste des priorités. Cette logique semble raisonnable lorsqu'une dépendance n'atteint jamais l'environnement de production. Elle ne tient toutefois pas la route dans le cas de Webpack, et ce pour deux raisons spécifiques.
Cet article explique en quoi consiste réellement le modèle de prise en charge de Webpack, pourquoi une version mineure 5.x « épinglée » est, dans la pratique, considérée comme du code non pris en charge, et comment traiter la chaîne de compilation comme une surface d'attaque sans pour autant retarder chaque mise à jour.
La compilation fonctionne toujours, donc personne n'y touche
La configuration Webpack d'un dépôt hérité est considérée comme intouchable, car elle continue de fonctionner, et personne ne veut être celui ou celle qui la rendra inopérante. Les systèmes de compilation stables ont tendance à devenir les logiciels les plus anciens de l'entreprise : rien n'oblige jamais personne à y jeter un œil.
Puis a lieu une réunion de triage. Un scanner signale une vulnérabilité CVE dans Webpack, quelqu’un y jette un coup d’œil, déclare « ça ne concerne que la phase de compilation », et le ticket se retrouve relégué au bas de la file d’attente, derrière tout ce qui semble présenter un véritable risque pour la production. Ce raisonnement semble logique. Or, il est doublement erroné.
La première erreur consiste à considérer la sortie de webpack comme distincte de l'outil d'emballage lui-même. webpack injecte son propre code d'exécution dans le fichier emballé ; ainsi, une faille dans ce code d'exécution devient une faille dans l'application que vous déployez.
La deuxième erreur consiste à supposer qu'un outil de compilation n'est accessible qu'au moment de la compilation. Le serveur de développement présente ses propres vulnérabilités, qui visent directement les ingénieurs qui l'exploitent. Et le problème plus profond réside dans le fait même de considérer les « devDependencies » comme un indicateur de risque. Il s'agit d'une étiquette de packaging, pas d'une frontière de sécurité. Un outil de packaging ne fait que rendre cela particulièrement évident, car une partie de ce qu'il génère se retrouve en production.
Webpack 4 est terminé et Webpack 5 ne dispose pas de version LTS
Webpack ne publie ni calendrier LTS, ni matrice de prise en charge, ni calendrier de fin de vie. Les corrections sont intégrées à la branche 5.x, qui fait l’objet d’un développement actif, plutôt qu’aux anciennes branches maintenues ; ainsi, une version mineure à laquelle vous restez ancré peut se retrouver obsolète dès qu’une correction est apportée en amont.
Webpack 4 a été lancé en février 2018, Webpack 5 est arrivé en octobre 2020, et la branche 4.x s’est terminée avec la version 4.47.0 en septembre 2023. La migration de la version 4 à la version 5 a pris des années à l’écosystème, et de nombreuses équipes ne l’ont jamais menée à bien. Si vous utilisez encore la version 4, vous exécutez du code qui ne bénéficie d’aucun correctif en amont.
Webpack 5 est plus stable, mais seulement en surface. La version actuelle est la 5.110.3, publiée en septembre 2026, et les deux corrections ci-dessous illustrent bien le problème concret, car chacune d’entre elles a été intégrée dans une version 5.x plus récente plutôt que d’être rétroportée vers les anciennes versions mineures concernées. Le projet’s Feuille de route pour 2026 a mis en place la gestion native du CSS, une cible de compilation universelle, TypeScript sans chargeurs, ainsi que les bases de Webpack 6, et le calendrier de publication a avancé rapidement sur tous ces fronts. La prise en charge expérimentale de TypeScript a fait son apparition dans la version 5.107, et la version 5.110 a déprécié css-loader, style-loader, et mini-css-extract-plugin au profit de la prise en charge CSS intégrée à Webpack. En d’autres termes, la version corrigée en amont est également celle qui ne cesse d’évoluer sous vos yeux.
Le saviez-vous ? Le fait d'utiliser « Webpack 5 » ne donne pratiquement aucune indication sur l'état de vos correctifs. Un dépôt verrouillé sur la version 5.76.1 accuse un retard de plus de trente versions mineures par rapport à la branche corrigée actuelle, même si Webpack 5 reste la version majeure actuelle du projet.
C'est précisément cet écart entre la « version principale prise en charge » et la « version corrigée » qui rend les audits délicats. Imaginez une interface client bancaire bloquée sur une version mineure 5.x parce que le pipeline est certifié et que tout changement de chaîne d’outils oblige à tout faire repasser par la certification. Changer de bundler implique de relancer ce processus ; le verrouillage est donc maintenu, et le code non pris en charge reste ainsi sur place. C’est exactement le type de situation pour laquelle le support étendu a été conçu : il permet à une équipe de rester à jour sur une branche dont elle ne peut pas facilement se détacher.
Certains bugs des outils de packaging finissent par se répercuter dans le navigateur
Certaines vulnérabilités de Webpack ne se situent pas du tout au niveau de l'étape de compilation. Elles se trouvent dans le code que Webpack intègre à votre bundle ; c'est pourquoi cet outil de bundling doit être pris en compte dans votre surface d'attaque en production et ne pas se limiter à votre liste de contrôle pour la phase de compilation.
43788 Voici un exemple clair. Il s'agit d'un gadget qui modifie le DOM dans Webpack’s AutoPublicPathRuntimeModule, et cela s'applique lorsque output.publicPath n'est pas défini ou est défini sur auto. L'avis publié par l'éditeur indique que les versions antérieures à la 5.93.0 sont concernées, tandis que la version 5.94.0 et les versions ultérieures ont été corrigées ; le NVD attribue à cette vulnérabilité un niveau de gravité « Moyen » avec un score de 6,4. Il est bon de savoir que auto c'est la valeur par défaut effective pour les cibles « web » et « web-worker » lorsque personne ne définit publicPath, ce n'est donc pas une configuration inhabituelle.
Le niveau « Medium » ne reflète pas pleinement la réalité opérationnelle. Le rapport de sécurité fait état d’une exploitation concrète dans la plateforme d’apprentissage en ligne Canvas, et le code vulnérable est généré directement dans le bundle plutôt que de se limiter à un environnement de CI. L’exploitation n’est toutefois pas automatique. Elle nécessite une page contenant des fichiers générés par Webpack et permettant à un attaquant d’injecter du code HTML sans script, dont le contenu n’a pas été suffisamment validé. name ou id attributs. Lorsque ces conditions sont réunies, le gadget peut influencer l'origine de chargement de vos scripts, ce qui constitue une attaque de type « cross-site scripting » s'exécutant dans les navigateurs de vos utilisateurs, initiée par votre outil de compilation.
28154 C'est un contraste intéressant, car il ne quitte jamais la compilation. Il s'agit d'un problème d'accès aux objets entre domaines dans ImportParserPlugin problème lié au traitement des commentaires « magiques », affectant les versions de Webpack antérieures à la version 5.76.0. Lors de la compilation, un attaquant capable d’influencer l’objet non fiable concerné pourrait amener Webpack à accéder à l’objet global du domaine hôte. Le NVD lui attribue un niveau de gravité « critique » avec un score de 9,8, tandis que Red Hat attribue à cette même faille un score de 9,1.
Recompiler avec la même version vulnérable de Webpack n’apporte aucune solution, et ce pour différentes raisons. Le code d’exécution à l’origine de la faille CVE-2024-43788 est réintroduit dans chaque bundle tant que Webpack n’a pas été corrigé, tandis que la faille CVE-2023-28154 réside dans le mécanisme d’analyse des commentaires de Webpack lui-même ; elle persiste donc tant que cette version est utilisée pour la compilation. Ces deux correctifs sont disponibles en amont depuis des années.
Attention : Avant de débattre des niveaux de gravité, vérifiez la version et la configuration. L'avis de sécurité indique que les versions de Webpack antérieures à la 5.93.0 sont concernées, tandis que la version 5.94.0 et les versions ultérieures ont été corrigées ; par conséquent, toute version antérieure à la 5.94.0 doit faire l'objet d'une vérification, et output.publicPath non défini ou activé auto C’est ce qui intègre le runtime concerné dans votre bundle. Vérifiez ensuite si votre application permet aux utilisateurs d’injecter du code HTML non validé name ou id caractéristiques, car ces conditions sont essentielles à l'exploitabilité.
Le fait qu'un projet dépende d'un autre ne signifie pas pour autant qu'il présente un faible risque
Même les vulnérabilités qui subsistent au moment de la compilation ne sont pas anodines, compte tenu de tout ce à quoi le code de compilation peut avoir accès. Un outil de regroupement s’exécute avec tout ce dont dispose le processus de compilation, c’est-à-dire généralement votre code source, vos variables d’environnement, vos identifiants et, dans de nombreux pipelines, vos jetons de publication. Cela représente une cible très riche.
30359 et les éléments connexes 30360 Ces deux failles se traduisent par un vol de code source à partir de webpack-dev-server, et toutes deux ont été corrigées dans la version 5.2.1, mais elles y parviennent de manière différente. La première exploite le fait qu’une requête de script classique provenant d’un <script> La balise n'est pas soumise à la politique du même origine ; ainsi, une page malveillante peut récupérer un bundle depuis un serveur de développement en cours d'exécution et, grâce à une légère « pollution des prototypes », extraire le code source de __webpack_modules__ en utilisant Function::toString. La deuxième faille concerne le détournement de connexions WebSocket entre sites : la vérification de l'origine autorisait le passage d'adresses IP provenant d'autres sources, exposant ainsi les développeurs utilisant des navigateurs non basés sur Chromium. Cette faille affecte les versions jusqu'à la 5.2.0.
Ce qui importe le plus aujourd’hui, c’est que la version 5.2.1 n’était pas la fin de l’histoire. Ce correctif s’appuyait sur le Sec-Fetch-Mode et Sec-Fetch-Site les en-têtes, que les navigateurs n'envoient que pour les origines potentiellement fiables ; ainsi, sur un protocole HTTP en clair, ces en-têtes sont absents et la vérification est entièrement ignorée. Cette faille, CVE-2026-6402, affecte webpack-dev-server jusqu'à la version 5.2.3, et la version 5.2.4 la corrige en définissant Cross-Origin-Resource-Policy: same-origin. La mise à disposition du serveur de développement via HTTPS constitue une solution de contournement documentée, et non un substitut à la mise à jour. La version 5.2.5 a ensuite corrigé la vulnérabilité CVE-2026-9595, qui concernait un proxy utilisateur à large portée avec ws: true intercepterait le WebSocket HMR du serveur de développement et le transmettrait au proxy cible, cookies et en-tête « Origin » compris. Par la suite, la version 5.2.6 a corrigé une faille de type « cross-site request forgery » (CSRF) via l’éditeur ouvert interne et les points de terminaison d’invalidation, ainsi qu’un déni de service déclenché par un en-tête Host ou Origin mal formé ; depuis, le package est passé à la version 6.0.0. Cette série de correctifs constitue un argument de poids pour ne pas considérer les découvertes relatives au serveur de développement comme du bruit de fond.
Réfléchissez aux personnes que cela met en danger. L’attaque publiée pour CVE-2025-30359 comporte une page malveillante qui demande un paquet à un serveur de développement sur localhost ; il suffit donc qu’un développeur navigue sur le Web alors qu’un serveur de développement est en cours d’exécution. L’attaquant a besoin du port et du chemin d’accès au point d’entrée de sortie, qui sont généralement configurés par défaut. Cela concerne aussi bien les prestataires utilisant des machines que vous ne contrôlez pas que toute personne laissant un serveur de développement allumé toute la journée pendant qu’elle navigue sur le Web, et rien de tout cela n’apparaît lors d’un scan axé sur l’environnement de production.
Sur le terrain : Quelqu'un règle host à 0.0.0.0 pour le tester sur un téléphone, puis oublie de rétablir la configuration initiale. Cette simple modification transforme un outil fonctionnant uniquement sur localhost en un outil à l'écoute du réseau, ce qui a une incidence sur les failles nécessitant un accès au réseau, comme le déni de service par en-tête mal formé. Ce n'est toutefois pas ce qui est à l'origine du vol de source inter-origines. Celui-ci fonctionne parfaitement contre localhost.
La question du triage n’a donc jamais porté sur le choix entre « localhost » et « tout le reste ». Il s’agit plutôt de la version exacte que vous utilisez, de savoir si les développeurs laissent un serveur de développement en marche pendant qu’ils naviguent sur Internet, s’il fonctionne via un simple protocole HTTP, et dans quelle mesure le port et le chemin de sortie sont faciles à deviner.
Une équipe utilisant la version 5.2.3 avec les paramètres par défaut est confrontée à une vulnérabilité réelle, quelle que soit l'adresse de liaison indiquée. Le protocole HTTPS atténue le risque d'exposition de la source dans la vulnérabilité CVE-2026-6402, mais il ne rend pas caduques les avis de sécurité publiés par la suite ; la version 5.2.4 ne constitue donc pas une garantie générale de sécurité. Les correctifs de la série 5.x s’étendent jusqu’à la version 5.2.6, et chaque avis de sécurité concerné doit être examiné au cas par cas plutôt que de faire l’objet d’une décision générale.
La migration cachée est plus importante que Webpack
Si ces « pins » persistent, ce n’est pas par paresse. Migrer une configuration Webpack bien rodée est un véritable projet, et les équipes s’en tiennent à ce qu’elles ont pour des raisons tout à fait valables : à commencer par les chargeurs et plugins personnalisés, les systèmes de build spécifiques aux frameworks qui s’y superposent, les configurations accumulées au fil des années de correctifs, la mise en cache sensible à la sortie, les versions de Node non prises en charge qui subsistent encore dans l’environnement d’intégration continue (CI), et la simple crainte de modifier un pipeline que personne ne comprend pleinement.
Une modification majeure n'a pas non plus pour effet de laisser les choses telles quelles. Elle peut modifier le regroupement, la résolution des modules, le comportement des polyfills, la gestion des ressources et la structure du résultat. Cela implique donc deux plans de test au lieu d'un seul, car le processus de compilation et l'application qui en résulte doivent tous deux être validés.
La meilleure approche consiste à cesser de considérer « webpack » comme un élément unique et à le décomposer en fonction de l’endroit où chaque composant s’exécute réellement. C’est précisément ce type de contexte d’exploitabilité qu’un document du Vulnerability Exploitability eXchange (VEX) est censé refléter, en précisant qu’un chargeur sur un environnement d’intégration continue (CI) et le code d’exécution contenu dans un bundle déployé ne présentent pas les mêmes risques.
| Composant | Où il s'exécute | Atteint le niveau de production | Priorité de triage |
|---|---|---|---|
| code d'exécution généré par webpack | Temps de compilation, puis dans le navigateur | Oui, lorsque le module d'exécution concerné se trouve dans le bundle | Haut |
| webpack-dev-server | Les machines des développeurs, ainsi que le réseau local lorsqu'il est accessible depuis l'extérieur | Non | En fonction de la version et de la configuration ; les risques sont les plus élevés dans les versions faisant l'objet d'avis de sécurité pertinents |
| Chargeurs et plugins | Temps de compilation, sur CI ou en développement | Parfois, cela dépend du chargeur | Au cas par cas |
| Outils de compilation transitifs | Durée de compilation | Rarement | Faible, sauf si accessible |
Un cadre décisionnel pour la mise en place d'un système existant
Aller de l'avant avec la version 5.x
Si la configuration est documentée et que les dépendances associées sont maintenues, passez à la version 5.x actuelle. C'est la solution la moins coûteuse et cela vous permettra de retrouver l'accès aux correctifs. Faites-le dès ce sprint plutôt que de repousser cette tâche au trimestre prochain.
Reconstruire le pipeline
Si la complexité héritée du passé a fini par dépasser son utilité, Rspack, Vite et esbuild méritent tous d’être étudiés sérieusement. Il faut toutefois être réaliste quant à leur coût. Ils sont certes plus rapides, mais la réécriture d’une configuration aboutie à l’aide de chargeurs personnalisés, de la « Module Federation » ou d’un fractionnement minutieux du code constitue un véritable projet qui, au final, n’apporte rien de visible pour l’utilisateur.
Apportez des corrections à la version épinglée et limitez l'ampleur de la migration
Si le pipeline est certifié, le remplacement du bundler n’aura pas lieu cette année. C’est là que le support étendu prend tout son sens : il maintient la branche épinglée à jour grâce aux correctifs, tandis que vous planifiez cette migration de grande envergure selon votre propre calendrier, sans avoir à agir dans l’urgence. Le support à cycle de vie illimité de TuxCare couvre les versions 5.50.0, 5.55.0, 5.76.1, 5.88.2 et 5.94.0 de webpack, ainsi que les versions de webpack-dev-server allant de 2.7.1 à 5.2.2, disponibles via npm.
Il faut toutefois bien comprendre ce qu'un « backport » permet de conserver. Il préserve votre version de Webpack, votre configuration et votre interface API, ce qui permet de limiter considérablement la portée de la recertification par rapport à une migration complète de la chaîne d'outils. En revanche, il ne permet pas de conserver un bundle de sortie identique au niveau des octets, car corriger le code d'exécution généré implique de modifier ce code.
L'approche de TuxCare en matière de prise en charge étendue de Webpack
Assurer une prise en charge à long terme d'un outil de compilation ne se résume pas à maintenir en vie une ancienne version. Le véritable travail réside dans les détails, et la plupart de ces tâches sont de celles qu'une équipe interne ne peut pas répéter mois après mois.
Il s'agit tout d'abord de surveiller Webpack et ses dépendances transitives prises en charge, puis de déterminer si un problème signalé affecte réellement la branche héritée, plutôt que de se fier uniquement à une plage de versions publiée. Cette approche contextuelle, qui tient compte du statut de fin de vie (EOL) et du risque lié aux dépendances transitives, permet à une équipe de se concentrer sur les véritables vulnérabilités plutôt que de passer au crible chaque ligne d'un rapport d'analyse.
À partir de là, les correctifs sont rétroportés sans entraîner les changements architecturaux présents dans les versions ultérieures. Chaque version corrigée est validée en termes de compatibilité et de régressions afin que les pipelines de compilation établis continuent de fonctionner, ce qui constitue généralement la véritable objection à l’application de correctifs sur une pile certifiée. TuxCare ne cherche pas à remplacer le Webpack en amont. Sa mission consiste en la gestion à long terme des versions que le projet a dépassées, avec les tests de régression et le travail de compatibilité dont les systèmes de production ont réellement besoin. Chaque version corrigée est livrée avec une nomenclature logicielle (SBOM) et un document VEX, et les artefacts comportent des signatures GPG détachées provenant du registre propre à TuxCare.
OpenJS et la longue durée de vie des outils essentiels
Webpack fait partie du projet OpenJS Impact, et le programme de pérennité de l'écosystème OpenJS ( ESP) a été mis en place pour permettre aux versions archivées, en fin de vie (EOL) et plus anciennes de bénéficier d'une couverture de sécurité commerciale, dont une partie des revenus est reversée aux projets et à la Fondation. TuxCare est membre « Gold » et partenaire de l'ESP; ce programme étant non exclusif, les responsables de maintenance restent libres de prendre en charge la version de leur choix.
Votre pipeline de compilation fait partie intégrante du produit, même si les clients ne le voient jamais. Un pipeline de compilation existant mérite de bénéficier du même plan de cycle de vie que l'application qu'il génère, et non d'une exemption permanente par rapport à celui que vous appliquez déjà partout ailleurs.
