
Escáner asíncrono de RCE para CVE-2025-55182 / CVE-2025-66478 — contaminación de prototipos → ejecución de código a través de React Server Actions.
Detección asíncrona, priorizada por versión y basada en la salida de canarios (canary) - sin adivinanzas a ciegas
[!WARNING] Solo para investigación de seguridad autorizada y pruebas de penetración. Escanear sistemas sin permiso explícito por escrito es ilegal. El autor no asume ninguna responsabilidad por el mal uso de esta herramienta.
React Server Actions pasa los datos de acción como datos de formulario multiparte directamente a un contexto de ejecución del lado del servidor. Debido a una sanitización insuficiente contra el envenenamiento de prototipos en versiones afectadas de react-server-dom-webpack, un atacante puede:
Object.prototype_response._prefix en el objeto de respuesta internoprocess.mainModule.require('child_process').execSync(cmd)
Esto otorga Ejecución Remota de Código no autenticada en cualquier aplicación Next.js de acceso público que utilice React Server Actions con una versión afectada de React.
CVE-2025-55182 - Amplio: afecta a paquetes de React 19 (react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack)
CVE-2025-66478 - Estricto: ruta de explotación específica de Next.js a través del endpoint de Server Action /
| Componente | Vulnerable | Parcheada |
|---|---|---|
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 | Solo builds canary 14.3.0-canary.77+ | Todas las versiones estables 14.x - NO afectadas |
| Next.js 13.x | - | NO afectadas |
Este escáner utiliza verificación de canarios basada en la salida - el método más fiable para confirmar la ejecución real de código con cero falsos positivos:
1. POST / con cabecera Next-Action + carga multiparte de envenenamiento de prototipos
2. La carga ejecuta: echo <canario_aleatorio>
3. El servidor vulnerable lanza un NEXT_REDIRECT con base64(canario) en la URL
4. Cabecera de respuesta: X-Action-Redirect: /login?a=<base64(canario)>
5. El escáner decodifica base64 → coincide con el canario → RCE confirmado ✓
allow_redirects=False es crítico: la confirmación reside en la cabecera, no en el destino de la redirección.
git clone https://github.com/InferiorAK/React2Shell
cd React2Shell
pip install -r requirements.txt
# Necesario solo si se usa el modo --browser para mejorar la detección de versión:
playwright install chromium
playwright install-deps chromium
Requisitos: Python 3.10+
# Un solo objetivo
python3 CVE-2025-55182_scanner.py -u https://target.com
# Escanear una lista de URLs
python3 CVE-2025-55182_scanner.py -f urls.txt
# Modo silencioso - solo imprime resultados RCE / Vulnerable
python3 CVE-2025-55182_scanner.py -f urls.txt -q
# Modo navegador - Chromium sin cabeza para detección precisa de versión
python3 CVE-2025-55182_scanner.py -f urls.txt -b
# Opciones completas - recomendado para escaneos a gran escala
python3 CVE-2025-55182_scanner.py -f urls.txt -b -q -c 3 -t 20
| Flag | Forma larga | Valor por defecto | Descripción |
|---|---|---|---|
-u | --url | - | URL de un solo objetivo |
-f | --file | - | Archivo que contiene una URL por línea |
-o | --output | outputs/vuln.txt | Archivo de salida para objetivos vulnerables |
-U | --unknown-output | outputs/unknown.txt | Archivo de salida para objetivos con versión desconocida |
-c | --concurrency | 5 | Conexiones HTTP concurrentes |
-t | --timeout | 15 | Tiempo de espera por solicitud (segundos) |
-q | --quiet | off | Imprimir solo filas RCE / VULNERABLE |
-b | --browser | off | Respaldo de detección de versión con Playwright Chromium sin cabeza |
Cada objetivo escaneado recibe uno de los siguientes veredictos:

| Veredicto | Color | Significado |
|---|---|---|
RCE | 🔴 Rojo | Canario confirmado en X-Action-Redirect - ejecución remota de código probada |
VULNERABLE | 🟠 Naranja | La versión está en el rango vulnerable; la carga RCE no devolvió eco (WAF / configuración parcheada / endpoint incorrecto) |
Unknown | 🟡 Amarillo | Next.js confirmado pero no se pudo detectar la versión - se intentó RCE de todas formas; guardado en outputs/unknown.txt para reintentar con modo navegador |
Not Vulnerable | 🟢 Verde | Versión confirmada como parcheada, o RCE devolvió explícitamente seguro |
Skipped | ⚪ Blanco | Versión confirmada como parcheada o sitio no Next.js - no se intentó PoC |
Error | ⚪ Blanco | Host inalcanzable o conexión fallida |
Archivos de salida (guardados en la carpeta outputs/, creada automáticamente):
outputs/vuln.txt — resultados RCE y VULNERABLE (se añaden en cada ejecución)outputs/unknown.txt — objetivos con versión Unknown; reintentar estos con -b para detección precisa de versión¿Por qué la versión aparece como
unknownen más del 90% de los sitios?
Next.js moderno 13+ que utiliza la arquitectura App Router nunca incrusta la versión del framework en el HTML estático. La versión solo existe en window.next.version después de que JavaScript se ejecute en un contexto real de navegador.
Sin --browser:
__NEXT_DATA__, scripts en línea y archivos de fragmentos con hashunknown - el filtrado basado en versión se evitaCon --browser (-b):
window.next.version directamente del DOM en vivo# Recomendado con modo navegador - reducir concurrencia (las páginas del navegador consumen muchos recursos)
python3 CVE-2025-55182_scanner.py -f urls.txt -b -c 3
El escáner ejecuta hasta 7 etapas, deteniéndose tan pronto como se encuentra una versión:
Etapa 1 │ Cabeceras de respuesta HTTP
│ X-Powered-By: Next.js X.Y.Z
│ x-nextjs-*, x-next-version
Etapa 2 │ Bloques <script> en línea (escaneo por bloque)
│ window.next = { version: "X.Y.Z", ... }
│ version:"X.Y.Z", router: ... ← patrón de clave adyacente en paquete minificado
│ "nextVersion":"X.Y.Z"
│ Next.js vX.Y.Z ← texto plano en meta / comentarios HTML
│ __NEXT_VERSION__ = "X.Y.Z"
Etapa 3 │ Blob JSON __NEXT_DATA__
│ Solo Pages Router - "version":"X.Y.Z" es seguro en este contexto
Etapa 4 │ URLs de fragmentos con hash (extraídas de <script src>)
│ /_next/static/chunks/*, /_next/static/app/*, /_next/static/runtime/*
│ Obtiene hasta 12 archivos de paquete reales, escanea cadenas de versión
Etapa 5 │ Fragmentos de respaldo con nombre fijo
│ main.js, framework.js, webpack.js, _app.js, pages/_app.js
Etapa 6 │ Endpoint /package.json
│ Modo desarrollo / servidores mal configurados exponen esto directamente
Etapa 7 │ Navegador sin cabeza Playwright [solo --browser / -b]
│ Evalúa window.next.version después de la ejecución completa de JS
│ Solo se activa cuando las etapas 1–6 devuelven "unknown"
Esta herramienta se publica solo con fines educativos y de investigación de seguridad autorizada.
El autor, InferiorAK, no es responsable de ningún daño causado por su mal uso.
Obtenga siempre permiso por escrito antes de probar cualquier sistema que no posea.
Hecho por InferiorAK
Mis Enlaces