Retour au blog
Sécurité

Next.js a publié deux nouveaux correctifs critiques d'exécution de code à distance le 14 octobre. L'un touche le modèle qu'il recommande désormais

19 octobre 2026 7 min de lecture

Le mercredi 14 octobre 2026, l'équipe Next.js a publié une mise à jour de sécurité hors calendrier : Next.js 16.4.1 sur la ligne Active LTS et 15.5.28 sur la ligne Maintenance LTS. Elle corrige deux vulnérabilités Critical, toutes deux des exécutions de code à distance sans authentification, et un déni de service de gravité High. L'équipe l'avait annoncée le 8 octobre et disait que deux des trois correctifs avaient été reportés de la publication de sécurité du 30 septembre « à cause d'une coordination avec l'amont ».

J'ai déjà écrit sur le correctif d'urgence du 25 août. Celui-ci mérite sa propre lecture, pour deux raisons. Le retard dit quelque chose sur qui tient désormais le calendrier de sécurité d'un framework. Et sur la ligne 16.x, le correctif n'existe que dans la 16.4, la version mineure qui a commencé le 6 octobre à recommander Cache Components comme « le meilleur choix pour toute application Next.js ». Je fais tourner Next.js en production, voici donc comment je lis les deux, et ce que je ferais avec une application existante.

Pourquoi les correctifs sont arrivés en deuxième vague

La chronologie est entièrement sur le blog de Next.js. Le 23 septembre, l'équipe a annoncé une publication planifiée pour le 30 septembre. Le 30 septembre, une note ajoutée à cette annonce a changé le décompte : la publication « corrige maintenant sept vulnérabilités au lieu de neuf », et les deux restantes, une Critical et une High, étaient « en attente de coordination avec l'amont ». La publication de septembre est sortie en 16.3.8 et 15.5.27. Le 8 octobre est arrivé l'avis pour le 14 octobre.

L'avis du 8 octobre ne nomme jamais l'amont. L'article du 14 octobre et les advisories, si. Deux des trois advisories d'octobre ont un jumeau dans le dépôt de React lui-même. L'exécution de code à distance dans les fonctions use cache (GHSA-673q-mjm6-r5xr) renvoie à GHSA-xqc2-xf4c-x3h3, « Unauthenticated Remote Code Execution in React Server Components ». Le déni de service des Server Actions renvoie à GHSA-h3gv-c5rc-p453. Les deux touchent les paquets react-server-dom pour webpack, Turbopack et Parcel, et React a rétroporté les correctifs sur quatre lignes de versions : 19.0.9, 19.1.10, 19.2.9 et 19.3.1. Le troisième bug se trouve dans « une bibliothèque amont utilisée pour l'optimisation d'images », et son contournement est sharp 0.35.5 ou plus récent.

Le registre npm montre la chorégraphie. Les quatre versions corrigées de react-server-dom-webpack côté React sont apparues entre 16 h 49 et 16 h 55 UTC le 14 octobre. Next.js 15.5.28 a suivi à 17 h 36, et 16.4.1 à 17 h 43. Quatre lignes React et deux lignes Next.js en moins d'une heure.

Next.js ne dit pas quel amont a causé l'attente, ni lequel des deux bugs Critical était celui reporté. Une chose en découle par élimination : septembre avait retenu une Critical et une High, et octobre n'a qu'une seule High. Le déni de service des Server Actions est donc sorti 14 jours après la publication à laquelle il était destiné.

C'est la leçon pratique. Quand un bug vit dans une couche partagée comme les React Server Components, un framework ne peut pas publier seul. Sa date devient celle de la publication coordonnée la plus lente. Pour qui fait tourner Next.js, les articles « mise à jour de sécurité à venir » sont le vrai signal : l'avis du 8 octobre laissait six jours pour réserver un créneau de mise à jour.

Ce qui est exposé, et le détail dans le lockfile

Le bug de use cache (CVSS 9,5) touche les versions 16.0.0 à 16.4.0, dans les applications App Router avec Cache Components, quand une fonction use cache renvoie plusieurs tableaux typés. Il n'y a pas de contournement, et l'advisory demande de mettre à jour « même si votre application n'a pas de fonctions similaires ». La première version corrigée est la 16.4.1. Il n'y a pas de 16.3.9 sur npm. Si tu es resté en 16.3.8 après septembre, le correctif de sécurité vient maintenant avec une mise à jour mineure : React 19.3, des changements dans Turbopack, de nouvelles API.

Le bug d'image, CVE-2026-96889 (aussi 9,5 dans l'advisory de Next.js), s'applique quand Next.js tourne sur un Linux basé sur glibc. L'advisory de sharp place la faille dans librsvg, que les binaires précompilés de sharp embarquent, donc le contournement est une version de sharp. Voici le détail facile à rater. Next.js 16.4.1 déclare sharp en ^0.35.5, donc la mise à jour force une version corrigée. Next.js 15.5.28 déclare ^0.34.3 || ^0.35.5. Une application 15.5 dont le lockfile résout déjà sharp 0.34.x satisfait cette plage et la garde après la mise à jour. L'advisory de Next.js nomme 0.35.5 comme plancher, et l'advisory de sharp pour le même CVE liste toute version inférieure à 0.35.5 comme vulnérable : il n'existe pas de 0.34.x corrigée. Sur la 15.5, je vérifierais quel sharp le lockfile résout réellement, pas seulement la version de Next.js. sharp 0.35.5 est sur npm depuis le 27 septembre, et sharp a publié son advisory le 30 septembre, deux semaines avant Next.js.

Le déni de service (CVSS 8,2) touche les applications App Router avec au moins une Server Action, à partir de la 13.0.0. Les applications Pages Router et celles sans Server Actions ne sont pas concernées. Aucun contournement hormis la mise à jour. Comme le bug d'image, qui remonte à la 10.0.0, il n'a pas de correctif sous la 15.5.28 : une application encore en 13.x ou 14.x doit changer de version majeure pour l'obtenir.

Cache Components a maintenant un historique de sécurité

Mets les deux publications côte à côte. La publication du 30 septembre comptait sept advisories, dont deux dans use cache : une clé de cache qui pouvait faire fuiter du contenu entre des valeurs de root params, et un remplissage de cache en attente qui pouvait faire fuiter du contenu du Draft Mode dans des réponses normales et des pages persistées. Les deux en Medium. Le 14 octobre a ajouté la Critical. Trois advisories sur dix, sur deux publications, touchent la directive au centre du modèle que Next.js recommande désormais.

Je n'y vois pas une raison d'éviter Cache Components. Les nouveaux chemins de code sont là où les chercheurs regardent, et c'est un modèle jeune qui reçoit beaucoup d'attention. J'y vois un coût d'adoption : si tu l'actives, ta cadence de correctifs doit être plus serrée qu'avant.

Voici la partie rassurante. Passer en 16.4.1 n'active pas Cache Components. L'article de la 16.4 dit qu'on utilise le modèle « en activant deux flags », cacheComponents et partialPrefetching. Seules les nouvelles applications créées par create-next-app l'ont par défaut. Le correctif et la migration sont deux décisions séparées.

Ce que la migration change vraiment

L'article de la 16.4 dit que Cache Components « deviendra le choix par défaut dans Next.js 17 » et ne donne aucune date pour la 17. Le coût se trouve dans le guide de migration :

  • Les configs de segment de route dynamic, revalidate et fetchCache produisent une erreur dès que le flag est activé, et exporter dynamicParams fait échouer le build.
  • use cache utilise par défaut un stockage en mémoire : les entrées sont supprimées quand une instance serverless est détruite, et elles sont limitées à un seul déploiement. L'ancien Data Cache de fetch et unstable_cache persistent entre les déploiements et les instances serverless. use cache: remote ou un cache handler survit à la destruction d'une instance, mais même avec un stockage durable le guide dit de s'attendre à ce que les valeurs en cache soient recalculées après un nouveau déploiement. C'est une ligne sur la facture d'hébergement, pas seulement un refactoring.
  • L'état des composants survit désormais à la navigation. Les formulaires gardent leurs valeurs et les listes déroulantes restent ouvertes, parce que les routes sont masquées avec Activity de React au lieu d'être démontées.
  • generateStaticParams qui renvoie un tableau vide produit maintenant une erreur.
  • new Date(), Math.random() et crypto.randomUUID() pendant le prérendu font échouer le build, même sur les routes exclues avec instant = false.
  • Cela exige Next.js 16.

Rien de tout ça n'est exotique. Tout est du travail.

L'horloge de la 15.x

La politique de support de Next.js dit que chaque version majeure reste en Maintenance LTS « pendant deux ans après sa sortie initiale ». Next.js 15 est sorti le 21 octobre 2024. Selon l'arithmétique de la politique elle-même, sa fenêtre se termine le 21 octobre 2026. La page n'indique aucune date de fin, et elle garde une clause pour corriger des versions hors politique « dans de rares circonstances ». Je planifierais quand même comme si la 15.5.28 pouvait être parmi les derniers correctifs de routine de cette ligne. Et comme Cache Components exige la 16, une application 15.x fait face à deux mises à jour, pas une.

Ce que je ferais

Corriger d'abord, seul. Une 16.x passe en 16.4.1 ou plus, la 15.5 passe en 15.5.28. Une seule pull request sans rien d'autre, pour qu'un retour arrière reste un retour arrière. Ensuite, confirmer sharp à 0.35.5 ou plus, dans le lockfile et sur le build déployé.

Si Cache Components est déjà actif en production, liste toutes les fonctions use cache. Tu étais concerné par le bug Critical et, si tu sers des aperçus Draft Mode, par l'un de ceux de septembre.

Sur la 15.x, planifie dès maintenant le passage à la 16, comme un projet à part.

Pour la migration, utilise une branche et le chemin incrémental que décrit le guide : le codemod cache-components-instant-false exclut chaque route de la validation, tu corriges les E/S synchrones (la seule chose que l'exclusion ne reporte pas), puis tu convertis les routes une par une. Avant de fusionner, déploie deux fois et observe le comportement du cache après le second déploiement, et clique dans chaque formulaire que tu as.

J'orchestre mon travail avec Claude Code, donc next upgrade --agent et la skill d'adoption de Cache Components visent des gens comme moi. La commande prépare pour l'agent des guides de migration, des codemods et des étapes de vérification. Ce que je vérifierais avant de laisser un agent la lancer : que la mise à jour de sécurité et la migration arrivent dans des pull requests séparées, que la version de sharp résolue est la bonne, et que la vérification inclut un vrai déploiement, pas seulement un build local. La 16.4 ajoute aussi experimental.agentUpgrade, dont la politique par défaut, 'security', te rappelle pendant next dev et next build les mises à jour qui corrigent des vulnérabilités connues dans ta version installée. Je la laisserais activée.

Le correctif est un changement de version. La migration change la façon dont ton application met en cache, rend et facture. Next.js 17 décidera du défaut. Toi, tu décides de l'ordre.

Sources

Un projet du même genre ?

Je conçois et déploie des produits comme celui-ci. Parlons-en.

Discutons