React2Shell : quand le framework de Meta ouvre la porte de vos serveurs aux attaquants
Avis d'expert
11 décembre 2025
L’une des bibliothèque JavaScript les plus utilisées, React et le framework Next.js sont cibles d’une vulnérabilité critique scorée au CVSS par la note maximale de 10.0. Cette faille dans le code source permet à un attaquant non authentifié de gagner directement un accès aux serveurs des applications.
Qu’est-ce que React et Next.js ?
Depuis plusieurs années, la bibliothèque open source JavaScript React, développée par Meta, anciennement Facebook, domine le marché. Cette bibliothèque permet de construire des interfaces utilisateur côté client, créant des composants interactifs.
L’un de ceux-ci, React Server Component – ou RSC, permet une exécution directement côté serveur avant d’être envoyé au navigateur.
Le framework Next.js, quant à lui, est directement basé sur React. Il facilite le développement d’applications web avec rendu hybride. Pour preuve, s’il en fallait, de l’usage massive de ce framework, le 08 novembre 2025, plus de 55 millions de sites l’utilisait.
Courbe d’utilisation de React, https://trends.builtwith.com/javascript/React
Qui est vulnérable ?
Le 03/12/2025, une vulnérabilité critique a été découverte dans React Server Component et par rebond sur Next.js, enregistrées sous deux CVE : CVE-2025-55182 et CVE-2025-66478. Pour anecdote, la CVE Next.js a été rejeté car faisait doublon à la première, et donc sans intérêt.
Appelée React2Shell, la CVE-2025-55182 fait partie du cercle très fermé des vulnérabilités avec un score CVSS de 10.0 (sur 10). En effet, l’une des bibliothèques JavaScript les plus utilisées, React de la version 19.0.0 à la 19.2.0 est vulnérable à une exécution de code par un attaquant non authentifié. Plus particulièrement, ce sont les packages suivants qui sont touchés par cette vulnérabilité :
- react-server-dom-parcel, pour le bundle Parcel
- react-server-dom-turbopack, pour le bundle Turbopack
- react-server-dom-webpack, pour le bundle Webpack
D’après les dernières recherches, il est possible d’exploiter la vulnérabilité même si aucune fonction React Server n’est utilisée mais que RSC est pris en charge.
Pour Next.js, les versions affectées sont les suivantes :
- 15.x
- 16.x
- 14.3.0-canary.77 et toutes les canary suivantes
Pour React, les frameworks et bundlers suivant utilisent les versions vulnérables de RSC :
- react-router
- waku
- parcel/rsc
- vitejs/plugin-rsc
- rwsdk
Analyse de la vulnérabilité
Tout part d’une désérialisation mal filtrée. Tout d’abord, la désérialisation est un processus convertissant des données linéaires en objet ou structure lisible par un programme.
Ici, une requête POST HTTP contient une charge utile qui lors de sa désérialisation dans une fonction de React Server permet d’exécuter du code et ainsi obtenir un accès sur le serveur. L’exploitation de la vulnérabilité est déjà accessible en ligne mais voici, en quelques mots comment elle marche.
La vulnérabilité se base sur la présence de différents modules Node.js exploitables. La chaîne de compromission complète requiert les modules vm ou child_process afin d’obtenir un accès direct au serveur. Pour autant, une variante peut être exploitée si seul le module fs est installé. Dans ce cas, la compromission sera indirecte : un attaquant pourra s’ajouter des accès SSH ou encore déclencher un accès serveur programmé, au redémarrage de l’app ou au prochain npm install par exemple.
La vulnérabilité se trouve dans les fichiers
react-server-dom-webpack-server.node.development.js,
react-server-dom-turbopack-server.node.development.js
et react-server-dom-parcel-server.node.development.js.
Pour bien comprendre la vulnérabilité, il faut remonter la pile d’exécution :
Pile d’exécution
Le chainage de différents défauts de protection du code avec une ligne vulnérable n’échappant pas correctement une entrée utilisateur permettent cette exécution de code à distance.
D’abord dans resolveServerReference :
var idx = id.lastIndexOf("#");
-1 !== idx && ((name = id.slice(idx + 1))
Ce code sépare le champ id sur le caractère ‘#’.
Puis, arrive la fonction vulnérable : requireModule avec l’appel à la fonction dans loadServerReference pour assigner la variable fn. Le code à l’origine de la vulnérabilité est moduleExports[metadata[2]].
Le problème réside dans l’accès à la variable entre double crochets : cela vérifie l’ensemble du prototype chain et pas seulement sa propriété.
Ainsi, si la payload est :
{id:'fs#constructor',bound:[]}
Cela donne le code suivant :
requireModule(['fs',[],'constructor'])
puis :
__webpack_require__('fs')['constructor'].
Enfin, la dernière ligne de code permettant la vulnérabilité se trouve dans fonction la
loadServerReference :
Return fn.bind.apply(fn, [null].concat(_ref)) ;
Cela passe le champ bound de la payload à fn.bind() et donc en argument du module passé dans le champ id.
Pour expliciter, dans la payload, le champ id représente le module et bound son argument. Or, pour que la vulnérabilité donne accès au serveur, le bound ne doit être vide afin d’éviter que cela retourne la fonction sans l’exécuter.
La requête post d’un attaquant doit ressembler à cela :
POST /formaction HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary
------Boundary
Content-Disposition: form-data; name="$ACTION_REF_0"
------Boundary
Content-Disposition: form-data; name="$ACTION_0:0"
{payload}
------Boundary--
Où :
$ACTION_REF_0 Permet de déclencher le parsing metadata
$ACTION_0 :0 Permet d’avoir le JSON contenant le l’id (le module) et le bound (l’argument de la fonction).
Impact de vulnérabilité
Une vulnérabilité aussi facile d’exploitation dans une bibliothèque JavaScript aussi massivement utilisée représente un risque considérable. Des milliers d’application Web sont vulnérables à une attaque simple à exploiter.
La CVE concernant Next.js est plus complexe à mettre en œuvre, en raison d’une vérification supplémentaire dans la fonction
resolveServerReference
qui rend l’exploitation plus complexe sans la rendre impossible pour autant.
Pouvez-vous avoir été ciblé ?
Pour savoir si vous avez été ciblé, vous devez vérifier vos logs. Ciblez les champs
$ACTION_REF_ et $ACTION_ID_
avec des mots clefs tels que #constructor ou encore
#__proto__
dans le champ ID. Regardez également dans les logs de l’application les références aux modules
vm, child_process ou encore process
par exemple.
Remédiation
Une remédiation rapide consiste à mettre à jours les bibliothèques, frameworks et bundler vulnérables.
Pour Next.js, les mises à jour sont les suivantes :
15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7 et revenez à une ancienne version de canary infériereur à 14.3
Pour React, mettre à jour aux dernières versions 19.0.1, 19.1.2, et 19.2.1
Pour plus de sécurité ou si la mise à jour n’est pas immédiatement possible, vous pouvez également ajouter des règles WAF afin de bloquer certains mots tels que
#constructor, #__proto__, #prototype, vm#runInThisContext, vm#runInNewContext, child_process#execSync
Références :
https://trends.builtwith.com/javascript/React
https://www.cve.org/CVERecord?id=CVE-2025-55182
https://github.com/ejpir/CVE-2025-55182-poc/
https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components
https://github.com/facebook/react/security/advisories/GHSA-fv66-9v8q-g76r
https://github.com/dwisiswant0/CVE-2025-55182www.tenable.com/blog/react2shell-cve-2025-55182-react-server-components-rce
https://www.openwall.com/lists/oss-security/2025/12/03/4
https://nvd.nist.gov/vuln/detail/CVE-2025-55182
https://www.facebook.com/security/advisories/cve-2025-55182
Auteur
Elisa SALFATI, Consultante/Auditrice Sécurité