
Scanner RCE asynchrone pour CVE-2025-55182 / CVE-2025-66478 — pollution de prototype → exécution de code via React Server Actions.
Détection asynchrone, priorité à la version, canaries basées sur la sortie - pas de devinette aveugle
[!WARNING] Réservé à la recherche en sécurité autorisée et aux tests d'intrusion uniquement. Scanner des systèmes sans autorisation écrite explicite est illégal. L'auteur décline toute responsabilité en cas d'utilisation abusive de cet outil.
Les React Server Actions transmettent les données d'action en tant que form-data multipart directement dans un contexte d'exécution côté serveur. En raison d'une insuffisance de l'assainissement de la pollution de prototype dans les versions affectées de react-server-dom-webpack, un attaquant peut :
Object.prototype_response._prefix sur l'objet de réponse interneprocess.mainModule.require('child_process').execSync(cmd)
Cela donne une exécution de code à distance non authentifiée sur toute application Next.js accessible publiquement utilisant les React Server Actions avec une version affectée de React.
CVE-2025-55182 - Large : affecte les packages React 19 (react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack)
CVE-2025-66478 - Strict : voie d'exploitation spécifique à Next.js via le point de terminaison Server Action /
| Composant | Vulnérable | Corrigé |
|---|---|---|
React react-server-dom-* | 19.0.0, 19.1.0, 19.1.1, 19.2.0 | 19.0.1, 19.1.2, 19.2.1+ |
| Next.js 16.x | 16.0.0 – 16.0.6 | 16.0.7+ |
| Next.js 15.x | 15.0.0-15.0.4, 15.1.0-15.1.8, 15.2.0-15.2.5, 15.3.0-15.3.5, 15.4.0-15.4.7, 15.5.0-15.5.6 | 15.0.5+, 15.1.9+, 15.2.6+, 15.3.6+, 15.4.8+, 15.5.7+ |
| Next.js 14.x | 14.3.0-canary.77+ constructions canary uniquement | Tous les 14.x stables - NON affectés |
| Next.js 13.x | - | NON affectés |
Ce scanner utilise une vérification par canarie basée sur la sortie - la méthode la plus fiable pour confirmer une exécution de code réelle avec zéro faux positif :
1. POST / avec en-tête Next-Action + charge utile multipart de pollution de prototype
2. La charge utile exécute : echo <random_canary>
3. Le serveur vulnérable génère NEXT_REDIRECT avec base64(canary) dans l'URL
4. En-tête de réponse : X-Action-Redirect: /login?a=<base64(canary)>
5. Le scanner décode base64 → correspond à la canarie → RCE confirmé ✓
allow_redirects=False est crucial - la confirmation se trouve dans l'en-tête, pas dans la destination de redirection.
git clone https://github.com/InferiorAK/React2Shell
cd React2Shell
pip install -r requirements.txt
# Required only if using --browser mode for improved version detection:
playwright install chromium
playwright install-deps chromium
Prérequis : Python 3.10+
# Single target
python3 CVE-2025-55182_scanner.py -u https://target.com
# Scan a list of URLs
python3 CVE-2025-55182_scanner.py -f urls.txt
# Quiet mode - only print RCE / Vulnerable results
python3 CVE-2025-55182_scanner.py -f urls.txt -q
# Browser mode - headless Chromium for accurate version detection
python3 CVE-2025-55182_scanner.py -f urls.txt -b
# Full options - recommended for large-scale scanning
python3 CVE-2025-55182_scanner.py -f urls.txt -b -q -c 3 -t 20
| Drapeau | Forme longue | Défaut | Description |
|---|---|---|---|
-u | --url | - | URL cible unique |
-f | --file | - | Fichier contenant une URL par ligne |
-o | --output | outputs/vuln.txt | Fichier de sortie pour les cibles vulnérables |
-U | --unknown-output | outputs/unknown.txt | Fichier de sortie pour les cibles de version inconnue |
-c | --concurrency | 5 | Connexions HTTP concurrentes |
-t | --timeout | 15 | Délai d'attente par requête (secondes) |
-q | --quiet | désactivé | Afficher uniquement les lignes RCE / VULNERABLE |
-b | --browser | désactivé | Repli de détection de version Playwright Chromium sans tête |
Chaque cible scannée se voit attribuer l'un des verdicts suivants :

| Verdict | Couleur | Signification |
|---|---|---|
RCE | 🔴 Rouge | Canarie confirmée dans X-Action-Redirect - exécution de code à distance prouvée |
VULNERABLE | 🟠 Orange | La version est dans la plage vulnérable ; la charge utile RCE n'a pas renvoyé d'écho (WAF / configuration corrigée / mauvais point de terminaison) |
Unknown | 🟡 Jaune | Next.js confirmé mais la version n'a pas pu être détectée - RCE tenté quand même ; enregistré dans outputs/unknown.txt pour nouvelle tentative en mode navigateur |
Not Vulnerable | 🟢 Vert | Version confirmée comme corrigée, ou RCE a explicitement renvoyé un résultat sûr |
Skipped | ⚪ Blanc | Version confirmée comme corrigée ou site non Next.js - aucune tentative de PoC |
Error | ⚪ Blanc | Hôte inaccessible ou connexion échouée |
Fichiers de sortie (enregistrés dans le dossier outputs/, créés automatiquement) :
outputs/vuln.txt — Résultats RCE et VULNERABLE (ajoutés à chaque exécution)outputs/unknown.txt — Cibles de version Unknown ; réessayez avec -b pour une détection précise de la versionPourquoi la version apparaît-elle comme
unknownpour plus de 90% des sites ?
Next.js 13+ moderne utilisant l'architecture App Router n'intègre jamais la version du framework dans le HTML statique. La version n'existe que dans window.next.version après exécution du JavaScript dans un contexte de navigateur réel.
Sans --browser :
__NEXT_DATA__, les scripts inline et les fichiers de chunk hachésunknown - le filtrage basé sur la version est contournéAvec --browser (-b) :
window.next.version directement depuis le DOM actif# Recommended with browser mode - reduce concurrency (browser pages are resource-heavy)
python3 CVE-2025-55182_scanner.py -f urls.txt -b -c 3
Le scanner exécute jusqu'à 7 étapes, s'arrêtant dès qu'une version est trouvée :
Étape 1 │ En-têtes de réponse HTTP
│ X-Powered-By: Next.js X.Y.Z
│ x-nextjs-*, x-next-version
Étape 2 │ Blocs <script> Inline (scan par bloc)
│ window.next = { version: "X.Y.Z", ... }
│ version:"X.Y.Z", router: ... ← motif de clé adjacente de bundle minifié
│ "nextVersion":"X.Y.Z"
│ Next.js vX.Y.Z ← texte brut dans meta / commentaires HTML
│ __NEXT_VERSION__ = "X.Y.Z"
Étape 3 │ Objet JSON __NEXT_DATA__
│ Pages Router uniquement - "version":"X.Y.Z" sûr dans ce contexte
Étape 4 │ URLs de Chunk Hachés (extraits de <script src>)
│ /_next/static/chunks/*, /_next/static/app/*, /_next/static/runtime/*
│ Récupère jusqu'à 12 fichiers de bundle réels, recherche de chaînes de version
Étape 5 │ Chunks de repli à nom fixe
│ main.js, framework.js, webpack.js, _app.js, pages/_app.js
Étape 6 │ Point de terminaison /package.json
│ Mode développement / serveurs mal configurés exposent cela directement
Étape 7 │ Playwright sans tête [--browser / -b uniquement]
│ Évalue window.next.version après exécution complète du JS
│ Déclenché uniquement si les étapes 1–6 renvoient "unknown"
Cet outil est publié uniquement à des fins éducatives et de recherche en sécurité autorisées.
L'auteur, InferiorAK, n'est pas responsable des dommages causés par une utilisation abusive.
Obtenez toujours une autorisation écrite avant de tester un système dont vous n'êtes pas propriétaire.
Créé par InferiorAK
Mes Liens