Mise à jour de sécurité Node.js : votre version reçoit-elle encore des correctifs ?
Le 21 octobre, Node.js a publié des correctifs de sécurité pour les lignes 22, 24 et 26. Quelles versions sont sûres, pourquoi Node.js 18 et 20 n’en recevront pas, et comment vérifier quelle version votre application utilise.
Le 21 octobre, Node.js a publié des correctifs de sécurité pour les lignes 22, 24 et 26. Quelles versions sont sûres, pourquoi Node.js 18 et 20 n’en recevront pas, et comment vérifier quelle version votre application utilise.
Seules les lignes de versions encore prises en charge ont reçu des correctifs, et les versions sûres sont 22.23.4, 24.22.1 et 26.12.1, ou des versions plus récentes de la même ligne. Node.js 18 et 20 sont déjà en fin de vie, si bien que cette mise à jour de sécurité de Node.js ne contient pas de correctif pour elles et n’en contiendra pas : si votre application tourne sur l’une d’elles, mettre à jour veut dire passer sur une autre ligne.
Le mercredi 21 octobre, le projet Node.js a fait paraître les publications de sécurité des trois lignes encore prises en charge, et le même jour PHP a publié des correctifs d’urgence pour des vulnérabilités qui ont reçu le nom PHP2Shell, mais ce sont deux événements distincts, d’une gravité différente. La publication de Node.js avait été annoncée à l’avance, le projet a classé ses vulnérabilités les plus graves comme élevées et non comme critiques, et le communiqué ne mentionne ni solutions de contournement ni attaques en conditions réelles. Cela n’autorise pas à reporter la mise à jour, mais cela déplace l’attention : cette fois, le plus grand risque n’est pas dans la publication elle-même, il est dans les versions qui ne l’ont pas reçue.
Ce que la mise à jour de sécurité Node.js d’octobre a corrigé
Le communiqué de Node.js énumère dix vulnérabilités : le projet en a classé quatre comme élevées, trois comme moyennes et trois comme basses, mais il n’a pas publié, cette fois, d’évaluation Common Vulnerability Scoring System (CVSS), et cet article reprend donc ce même classement.
La plus grave est CVE-2026-111497. Le projet la nomme un out-of-bounds write du décodeur Brotli, une écriture au-delà de la mémoire allouée qui permet une exécution de code à distance (RCE), et il la classe comme élevée. Brotli est un format de compression dont le décodeur est intégré à Node.js, et les notes de publication décrivent le correctif comme une modification de cette bibliothèque intégrée. Le communiqué ne dit pas par quel chemin la vulnérabilité est atteignable, et la description du correctif chez les auteurs de Brotli ne dit, elle aussi, que ceci : un flux de données invalide est désormais reconnu plus tôt. Aucune fonction précise n’est donc nommée ici, et l’on peut affirmer avec sûreté seulement que le bogue du décodeur concerne avant tout les applications qui décompressent des données Brotli venues d’une source à laquelle elles ne peuvent pas se fier.
Trois autres vulnérabilités touchent le contrôle des certificats TLS, et ce n’est pas le même cas trois fois. La première, classée élevée, ne concerne que les lignes 26 et 24 : on peut contourner la hostname verification, le contrôle qui relie le certificat au nom d’hôte auquel Node.js se connecte, si l’adresse IP est écrite en chiffres pleine chasse, par exemple 127.0.0.1. La deuxième, élevée elle aussi, concerne les trois lignes : le contrôle peut être contourné si, sans lecture stricte, le nom d’hôte peut être lu comme une adresse IP. La troisième est moyenne et concerne elle aussi les trois lignes : une notation IPv4 non standard permet au nom DNS indiqué dans le certificat d’attester une adresse IP. Dans les notes de publication, les correctifs sont formulés brièvement : les adresses IP écrites de façon atypique sont désormais refusées, et une régression dans la normalisation des adresses IP a été corrigée à part. Dans les trois cas, Node.js est le client, c’est-à-dire que c’est lui qui ouvre une connexion chiffrée vers un autre serveur, et non lui qui sert ses propres visiteurs.
La quatrième vulnérabilité classée élevée se trouve dans la fonction dns.resolve, qui tronquait les noms contenant un caractère nul. Parmi les vulnérabilités moyennes, il y a un bogue de réutilisation des connexions HTTP, dans lequel une réponse écrite sur la connexion avant l’envoi de la requête pouvait être traitée comme la réponse à cette requête, et un bogue à cause duquel le cache d’aléa de crypto.randomUUID() et de randomInt() était enregistré dans les startup snapshots et dans un seul fichier exécutable (single executable application, SEA), de sorte que chaque processus répétait les mêmes valeurs. Trois vulnérabilités classées basses concernent le traitement des fichiers ZIP et le modèle de permissions de Node.js.
Le bogue du cache d’aléa mérite d’être compris avec précision, parce que, dans le cas ordinaire, il n’a aucun effet. Il ne concerne que les projets qui démarrent depuis un startup snapshot qu’ils ont eux-mêmes produit, ou qui sont distribués comme un seul fichier exécutable (SEA), et il signifie alors que chaque processus lancé depuis le même fichier recevait les mêmes valeurs « aléatoires ». Si un tel projet fabriquait des identifiants ou des codes temporaires avec crypto.randomUUID() ou randomInt(), ces valeurs pouvaient se répéter d’un processus à l’autre, et il est donc utile, après le correctif, de vérifier qu’aucune d’elles n’est utilisée là où elle doit rester impossible à deviner.
La publication met aussi à jour plusieurs dépendances intégrées, selon la ligne : c-ares, OpenSSL, SQLite et Undici, sur laquelle repose la fonction fetch intégrée. Le CA store, la liste des autorités de certification (AC) de confiance, a également été mis à jour à la suite d’un certificat intermédiaire eMudhra compromis, et les connexions TLS refusent désormais les chaînes qui contiennent des clés publiques bloquées.
Quelles versions sont sûres
Les versions corrigées sont au nombre de trois, une pour chaque ligne prise en charge : 22.23.4, 24.22.1 et 26.12.1. Tout ce qui est plus ancien sur sa ligne est concerné. Les dix vulnérabilités ne touchent pas toutes les lignes : la ligne 26 les a toutes les dix, la ligne 24 en a huit, et la ligne 22 en a sept, parce que deux bogues classés bas n’existent que sur la ligne la plus récente et qu’un bogue TLS ne concerne pas la ligne 22.
Mettre à jour à l’intérieur de la ligne est le plus petit pas possible, et c’est d’ordinaire aussi le changement le plus sûr que l’on puisse faire en production. Même ce pas-là peut modifier le comportement, et il y a cette fois un exemple concret : le correctif du contrôle TLS refuse désormais les adresses IP écrites de façon atypique. Si une application utilisait autrefois une telle notation dans ses connexions vers un autre serveur, la connexion peut échouer après la mise à jour. C’est une faille de sécurité corrigée, non un bogue nouveau, mais il vaut mieux le savoir avant la mise à jour qu’après.
La ligne de versions est plus importante que le numéro de version
Jusqu’à Node.js 26, chaque version majeure suit un même cycle : elle est d’abord la version actuelle (Current), puis les versions de numéro pair reçoivent le support à long terme actif (Active LTS), elles passent ensuite en phase de maintenance LTS, où elles ne reçoivent que des correctifs critiques de bogues et des correctifs de sécurité, et le support finit par cesser tout à fait, tandis que les versions de numéro impair, jusqu’à la ligne 25, ne recevaient pas de support à long terme. Dès Node.js 27, le cycle change : selon le calendrier des publications, chaque ligne recevra un support à long terme et restera en phase Active LTS pendant les 30 mois de support, sans phase de maintenance LTS. Le projet écrit lui-même que les applications de production ne doivent utiliser que des versions en support à long terme actif (Active LTS) ou en phase de maintenance LTS.
Pour les lignes actuelles, les prochains changements de phase tombent à deux dates. Selon le calendrier des publications de Node.js, la ligne 24 est passée en phase de maintenance LTS le 20 octobre, la veille de la publication de sécurité, et la ligne 26 recevra le support à long terme le 28 octobre. La ligne 22 est en phase de maintenance LTS depuis le 21 octobre 2025 et arrivera en fin de vie le 30 avril 2027, tandis que la ligne 24 y arrivera le 30 avril 2028.
La conséquence pratique est simple : la question « avons-nous la dernière version » ne dit pas grand-chose à elle seule, alors que la question utile est « sur quelle ligne sommes-nous, et jusqu’à quelle date recevra-t-elle des correctifs ». La réponse à la première change tous les mois, la réponse à la seconde — une fois tous les deux ans, et c’est précisément pour cela que la seconde est facile à oublier.
Node.js 18 et 20 : il n’y aura pas de correctif
Le communiqué de Node.js contient une phrase qui, cette fois, compte plus que les dix vulnérabilités : les versions en fin de vie sont toujours concernées par une publication de sécurité, et aucun correctif n’est publié pour elles, ni maintenant ni plus tard, parce qu’une ligne en fin de vie ne reçoit plus aucune publication.
Selon le calendrier des publications, la ligne 16 est arrivée en fin de vie le 11 septembre 2023, la ligne 19 le 1er juin 2023, la ligne 18 le 30 avril 2025 et la ligne 20 le 30 avril 2026. La dernière date est la plus importante : la ligne 20 est en fin de vie depuis un peu moins de six mois, et un projet qui a été commencé dessus peut encore tourner sans aucun problème visible. C’est précisément ce qui rend la situation trompeuse, parce que rien dans son fonctionnement n’indique que les correctifs de sécurité ne lui sont plus destinés.
Pour les entreprises qui ne peuvent pas passer rapidement sur une ligne prise en charge, le communiqué de Node.js mentionne une possibilité : un support commercial pour les versions après la phase de maintenance LTS, proposé par les partenaires de l’OpenJS Ecosystem Sustainability Program. C’est un service payant, et c’est une solution temporaire, non un substitut au passage.
Comment vérifier quelle version de Node.js votre application utilise
La vérification prend quelques minutes, mais il y a un endroit où il est facile de la faire de travers : la version de Node.js que le terminal affiche n’est pas toujours celle avec laquelle l’application tourne.
Hébergement avec cPanel : la version utilisée s’affiche dans la section Software → Setup Node.js App, où chaque application a sa propre entrée dans la liste et où la version se choisit dans cette liste. La liste ne contient que les versions que l’hébergeur a installées sur le serveur. La commande node -v peut, sur un tel hébergement, afficher une autre version que ce réglage, et il faut donc regarder l’entrée de l’application elle-même.
Votre propre serveur : la commande node -v affiche la version qui arrive la première dans le chemin du système, mais un gestionnaire de processus, par exemple PM2 ou un service systemd, peut lancer le programme avec un exécutable tout à fait différent. La réponse la plus fiable est celle que le processus donne sur lui-même : la valeur de process.version, par exemple écrite dans le journal au moment du démarrage.
Conteneurs : dans Docker, la version est fixée par l’image conteneur, et non par la machine hôte. Une image construite avant le 21 octobre ne contient pas le correctif, quel que soit le nombre de redémarrages du conteneur, et il faut donc reconstruire l’image avec une image de base à jour.
Si vous n’avez pas l’accès : la question s’adresse alors à l’hébergeur ou au développeur qui maintient l’application. Une formulation qui épargne un échange de messages : « Quelle version de Node.js notre application utilise-t-elle ? Sur sa ligne, est-elle au moins 22.23.4, 24.22.1 ou 26.12.1 ? Si elle est sur une ligne en fin de vie, par exemple 18 ou 20, quand le passage est-il prévu ? »
Que faire aujourd’hui
Pour aujourd’hui, l’ordre est le suivant : d’abord mettre Node.js à jour jusqu’à la version corrigée de votre ligne et redémarrer chaque processus qui l’utilise, ensuite reconstruire tout ce dans quoi l’environnement d’exécution est intégré, et seulement ensuite prévoir le passage pour les projets qui tournent sur des lignes en fin de vie.
Premièrement, mettez à jour à l’intérieur de la ligne : vers 22.23.4, 24.22.1 ou 26.12.1, selon la ligne où vous êtes. Dans le cas d’un hébergement, c’est le fournisseur qui le fait, et votre travail consiste à vérifier que l’application utilise bien la version mise à jour.
Deuxièmement, redémarrez les processus : un processus déjà en cours continue d’utiliser le Node.js avec lequel il a été lancé, et le remplacement du fichier sur le disque ne le concerne pas. Il en allait de même pour PHP2Shell : le package a été remplacé, mais l’ancien processus continue de tourner avec l’ancien code.
Troisièmement, reconstruisez là où l’environnement d’exécution est intégré : les images conteneur Docker doivent être reconstruites avec une image de base à jour. Si vous distribuez le programme comme un seul fichier exécutable (SEA), Node.js lui-même y est intégré, si bien que la mise à jour de la version installée sur le système ne le concerne pas, et le fichier doit être reconstruit avec la version corrigée. Il en va de même pour les startup snapshots, que le bogue du cache d’aléa concerne.
Quatrièmement, si vous êtes sur la ligne 18 ou 20, prévoyez le passage : c’est un plus gros travail qu’une mise à jour à l’intérieur de la ligne, il vaut donc la peine de le commencer maintenant, et l’ordre des opérations est décrit dans la section suivante.
Comment passer de Node.js 18 ou 20
Le passage d’une version majeure à une autre n’est pas l’affaire d’une seule commande, et il vaut mieux le faire dans l’ordre. Il faut d’abord choisir la cible : dans la plupart des cas, c’est la ligne 24, qui recevra des correctifs jusqu’au 30 avril 2028 ; la ligne 22 n’est un choix raisonnable que si une dépendance importante ne prend pas encore la ligne 24 en charge, parce que le support de la ligne 22 s’arrête un an plus tôt.
Il faut ensuite trouver tous les endroits où le projet fixe sa version de Node.js, parce qu’il y en a presque toujours plusieurs : le champ engines de package.json, les fichiers .nvmrc ou .node-version, l’image de base du Dockerfile, la configuration de l’environnement d’intégration continue (CI) et le réglage du panneau d’hébergement. Si l’on n’en change qu’une partie, des versions différentes tournent dans des environnements différents, et les erreurs apparaissent là où elles sont le plus difficiles à trouver.
Le projet doit ensuite être réinstallé dans un environnement de test avec la nouvelle version, et les tests doivent être lancés. Une attention particulière revient aux packages qui contiennent du code compilé : ils sont construits pour une version précise de Node.js, et il peut donc falloir les reconstruire ou les mettre à jour après le passage. Pour chaque version majeure, Node.js publie une liste des changements, dans laquelle les changements susceptibles de casser le code existant sont signalés à part, et il vaut mieux la lire avant le passage qu’après.
Alors seulement vient l’environnement de production : le changement de version, le redémarrage des processus, et la vérification que process.version affiche la nouvelle version. L’ancienne version peut rester disponible quelques jours pour un retour arrière, mais pas davantage, parce que c’est précisément la version qui n’aura plus de correctif.
Ce qui n’est pas mis à jour avec Node.js
Mettre Node.js à jour corrige l’environnement d’exécution lui-même et les bibliothèques qui y sont intégrées, mais pas tout ce que l’application utilise, et c’est précisément là que restent le plus souvent des failles que personne ne voit.
Packages installés à part : si le projet utilise, dans ses dépendances, le package undici venu de npm plutôt que le fetch intégré, ce package se trouve dans le dossier node_modules du projet, et la publication n’y touche pas. Il en va de même pour toutes les autres dépendances : c’est le gestionnaire de packages qui les met à jour, et seulement lorsque quelqu’un le lance.
Le CA store, liste des autorités de certification de confiance : par défaut, Node.js n’utilise pas la liste d’autorités de certification du système d’exploitation, mais la sienne, intégrée, et la documentation dit qu’il s’agit d’une copie de la liste Mozilla, figée au moment de la publication. Un changement comme la réaction de cette publication au certificat intermédiaire eMudhra compromis n’arrive donc au programme qu’avec la mise à jour de l’environnement d’exécution, et non avec les mises à jour du système d’exploitation, sauf s’il a été configuré expressément pour utiliser la liste du système.
Comment ne pas manquer la prochaine publication
Les publications de sécurité sont annoncées à l’avance sur la page de sécurité du projet, avec le jour prévu pour la publication, et c’est exactement ce qui s’est passé cette fois. Ce mercredi n’était donc pas une surprise pour ceux qui surveillent cette page : la mise à jour pouvait être prévue d’avance, au lieu de chercher du temps le jour même.
En pratique, cela veut dire que quelqu’un doit être responsable de cette surveillance. Sur un hébergement infogéré, c’est le fournisseur qui s’en charge, mais sur votre propre serveur, ou sur un projet que votre équipe maintient elle-même, il est utile de savoir qui suit exactement les communiqués du projet, qui décide de la mise à jour, et qui vérifie qu’ensuite tout fonctionne. Si la réponse à ces questions est « personne en particulier », c’est précisément là qu’est le plus grand risque, et non dans l’une des dix vulnérabilités.
Si Node.js n’est pour vous qu’un build tool
Sur beaucoup de sites Laravel et WordPress, Node.js ne tourne pas du tout sur le serveur : il fait tourner Vite, ou un outil du même genre, qui prépare les fichiers CSS et JavaScript à partir du code source, puis il s’arrête. La situation diffère alors de celle d’une application qui sert elle-même les requêtes, parce que le processus de build ne répond pas aux requêtes venues d’internet et ne décompresse pas des données que lui enverraient des visiteurs inconnus.
Que la situation diffère ne veut pas dire qu’elle n’a pas d’importance. Les build tools tournent sur les ordinateurs des développeurs et dans l’environnement d’intégration continue, ils téléchargent des packages et ouvrent des connexions vers d’autres serveurs, et les descriptions des vulnérabilités sont trop courtes pour dire avec sûreté lesquels de ces chemins sont concernés. Mettre Node.js à jour vaut la peine là aussi, seulement dans le bon ordre : d’abord les serveurs où Node.js tourne en ligne, ensuite les ordinateurs des développeurs et l’environnement d’intégration.
Il y a aussi une seconde raison, qui n’a rien à voir avec cette semaine. L’environnement de build reste souvent sur la version de Node.js avec laquelle le projet a été commencé autrefois, et un jour une nouvelle version d’un outil refuse simplement de fonctionner avec elle. Le passage vers une ligne prise en charge se fait alors dans la précipitation, et à un mauvais moment, si bien qu’il est plus simple de le faire maintenant, pendant que c’est un travail prévu.
Ce que cela a signifié sur notre hébergement
Notre hébergement infogéré est un emplacement sur notre propre serveur, et chaque client y choisit la version dans le panneau d’hébergement. Sur notre serveur, les lignes 22 et 24 tournent déjà avec les versions corrigées 22.23.4 et 24.22.1. Pour les clients dont les projets utilisent ces lignes, il n’y a rien à faire, sinon vérifier que le processus a été redémarré après la mise à jour.
Il faut aussi dire l’autre côté, honnêtement : des lignes en fin de vie restent proposées au choix sur le serveur, et il n’y a pas de correctif pour elles — ni sur notre serveur, ni sur celui de quiconque, parce que Node.js ne publie pas un tel correctif. Si l’une d’elles est choisie pour votre projet, mettre à jour veut dire passer sur la ligne 22 ou 24, et le mieux est de le faire en vérifiant en même temps qu’après le passage tout fonctionne comme avant.
Notre hébergement infogéré commence à 45 € par mois, et les environnements d’exécution maintenus font partie de ce que cette somme paie. Si votre application tourne encore sur Node.js 18 ou 20, discutons de la migration, avant que le jour d’une prochaine publication de sécurité ne l’impose.
Vos questions fréquentes.
Node.js : quelle version est sûre ?
Les versions sûres sont 22.23.4, 24.22.1 et 26.12.1, ou une version plus récente de la même ligne. Tout ce qui est plus ancien sur sa ligne est concerné. Pour les versions dont la ligne est en fin de vie, par exemple Node.js 18 et 20, il n’existe aucune version sûre, parce qu’aucun correctif n’est publié pour elles.
J’ai Node.js 18 ou 20. Que faire ?
Les deux lignes sont en fin de vie : la ligne 18 depuis le 30 avril 2025, la ligne 20 depuis le 30 avril 2026. Il n’y a pas de correctif pour elles et il n’y en aura pas, donc la seule issue est de passer sur une ligne prise en charge. La ligne 24 recevra des correctifs jusqu’au 30 avril 2028, la ligne 22 jusqu’au 30 avril 2027. Le passage mérite d’être essayé d’abord dans un environnement de test.
Cette mise à jour de sécurité de Node.js est-elle la même chose que PHP2Shell ?
Non. Les deux événements ont eu lieu le 21 octobre, mais ils sont distincts. PHP2Shell, c’étaient deux vulnérabilités critiques dans PHP lui-même. La publication de sécurité de Node.js avait été annoncée à l’avance, ses vulnérabilités les plus graves sont classées élevées, et le communiqué ne mentionne pas d’attaques en conditions réelles.
Mettre Node.js à jour suffit-il, si l’application tourne déjà ?
Non, il faut redémarrer le processus. Un processus déjà en cours continue d’utiliser le Node.js avec lequel il a été lancé. Si l’application est dans une image conteneur Docker, ou distribuée comme un seul fichier exécutable (SEA), l’environnement d’exécution lui-même y est intégré, et il faut la reconstruire avec la version corrigée.
Sur notre site Laravel ou WordPress, Node.js n’est utilisé que pour le build avec Vite. Cela nous concerne-t-il ?
Moins qu’une application qui sert elle-même les requêtes, parce que le processus de build ne répond pas aux requêtes venues d’internet. Les build tools téléchargent toutefois des packages et ouvrent des connexions vers d’autres serveurs, donc mettre Node.js à jour vaut aussi sur les ordinateurs des développeurs et dans l’environnement d’intégration continue, mais seulement après les serveurs.
Y a-t-il des solutions de contournement, s’il n’est pas possible de mettre à jour tout de suite ?
Le communiqué de Node.js n’en mentionne pas. La seule recommandation est d’utiliser une version prise en charge, selon le calendrier des publications. Pour les versions en fin de vie, le projet mentionne un support commercial, proposé par les partenaires de l’OpenJS Ecosystem Sustainability Program.
Comment voir quelle version de Node.js une application utilise sur un hébergement cPanel ?
Dans la section Software → Setup Node.js App, où chaque application a sa propre entrée dans la liste, avec la version choisie. La commande node -v dans le terminal peut afficher une version différente du réglage de l’application, donc regardez l’entrée de l’application elle-même.
Serveurs, hébergement et maintenance dans l’UE — à Francfort, Helsinki ou Riga, avec une supervision 24/7. Infogérance complète : mises à jour, sécurité et performance, sauvegardes automatiques dont la restauration est testée, certificats SSL, CDN et protection anti-DDoS. Nous vous migrons depuis votre hébergeur actuel sans interruption de service et adaptons les ressources à la charge.