React RCE-kwetsbaarheid (CVE-2025-55182) – probleem en oorzaak
In het begin van december 2025 werd de React Server Components-kwetsbaarheid (CVE-2025-55182, ook wel React2Shell / React4Shell genoemd) bekendgemaakt. Deze kwetsbaarheid, met een CVSS-score van 10.0, maakt het mogelijk om zonder authenticatie op afstand code uit te voeren (RCE). Er zijn al PoC’s en daadwerkelijke scans/aanvallen waargenomen.
In dit artikel wordt “wie, waarom en hoe gevaarlijk” op een meer gestructureerde manier samengevat.
Samenvatting in één oogopslag
-
Kern van het probleem De React Server Components (RSC) gebruiken een fout in de deserialisatie‑logica van het Flight-protocol, waardoor een aanvaller een aangepaste aanvraag kan sturen die willekeurige JS‑code op de server uitvoert.
-
Belangrijkste getroffen componenten
react-server-dom-webpack / -parcel / -turbopack19.0 / 19.1.0 / 19.1.1 / 19.2.0-
Deze zijn ingebouwd in Next.js 15.x, 16.x, 14.3.0‑canary.77 en later (bij gebruik van App Router)
-
Traditionele React SPA in de browser Een puur client‑side React‑app die geen RSC/Server Actions of server‑rendering gebruikt, wordt niet beïnvloed.
-
Wat je moet doen als je eerder Next.js hebt gebruikt 1. Controleer de versies van
react-server-dom-*/nextin je project. 2. Werk React bij naar 19.0.1 / 19.1.2 / 19.2.1 of hoger. 3. Werk Next.js bij naar de gepubliceerde patch‑versies (15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7, etc.) of downgrade naar een stabiele versie. 4. Als je server al publiekelijk toegankelijk is, controleer dan logs, WAF‑regels en andere verdachte signalen.

Wat is de gevonden kwetsbaarheid?
Samengevat, de React‑team heeft het volgende uitgelegd:
- Doelwit: React Server Components (RSC) implementatie (
react-server-dom-*) - Kwetsbare sectie: de deserialisatie (Flight‑protocol) logica die RSC‑data van client naar server verzendt
- Aanvalsmethode:
- De aanvaller stuurt een speciaal aangepaste Flight‑payload naar de RSC/Server Actions HTTP‑endpoint.
- De server vertrouwt deze data en deserialiseert het, waardoor interne module‑laden/objectaanmaken wordt beïnvloed door de aanvaller‑input.
- Dit resulteert in willekeurige code‑uitvoering (RCE) op de server.
Belangrijk: de aanval is unauthenticated. Een Next.js RSC‑server die publiekelijk toegankelijk is, is vanaf het moment van blootstelling een doelwit.
Exacte voorwaarden voor de kwetsbaarheid
1. React/Next.js versie‑voorwaarden
- React RSC gerelateerde pakketten
react-server-dom-webpackreact-server-dom-parcel-
react-server-dom-turbopack -
Kwetsbare versies
-
19.0, 19.1.0, 19.1.1, 19.2.0
-
Patch‑versies
-
19.0.1, 19.1.2, 19.2.1
-
Next.js (App Router)
- Kwetsbaar:
- 14.3.0‑canary.77 en hoger
- 15.x, 16.x (standaard App Router met RSC)
- Gepatcht:
- 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7, etc.
2. Architectuur/Runtime‑voorwaarden
Alle onderstaande voorwaarden moeten allemaal aanwezig zijn voor een daadwerkelijke aanval:
- RSC gebruikt * Next.js App Router of een ander RSC‑ondersteunend framework
- React‑code draait op de server * Node.js of vergelijkbare omgeving waar RSC/Server Actions actief zijn
- Server is via HTTP publiekelijk of intern bereikbaar * Een aanvaller kan HTTP‑verzoeken sturen
Omgekeerd zijn de volgende omgevingen vrijwel irrelevant voor deze kwetsbaarheid:
- CRA/Vite‑gebaseerde pure client‑side React SPA
- Gebruik van RSC/Server Actions niet, alleen statische bundels op S3/CDN
- “React draait alleen in de browser, server is een volledig andere stack” (bijv. React + Django REST, React + FastAPI)
Waarom React‑DRF en React‑FastAPI relatief veilig waren
Wanneer React wordt gecombineerd met een Python‑backend zoals Django REST Framework of FastAPI, ontstaat er geen probleem. Redenen:
- React code draait niet op de server * React draait alleen in de browser; Django/FastAPI is puur een HTTP‑API‑server. * De server hoeft het Flight‑protocol of RSC niet te begrijpen.
- Duidelijke communicatie‑grens * React ↔ server communicatie gebeurt via JSON/HTTP‑API. * De server laadt geen React‑modules of gebruikt client‑gegeven metadata voor module‑laden.
- Geen RSC/Server Actions/Flight‑protocol * De aanvalspunt is “React‑code op de server die RSC‑payload verwerkt”. * Django/FastAPI bevat die code niet.
Kortom, de kwetsbaarheid is een structureel probleem dat alleen voorkomt in geïntegreerde frameworks zoals Next.js.
Flight‑protocol en prototype‑pollutie op de server
Technisch gezien volgt de kwetsbaarheid het klassieke patroon: Flight‑protocol deserialisatie → prototype‑pollutie → RCE.
1. Problematische code‑patroon
Een conceptueel voorbeeld van de kwetsbare functie:
// Kwetsbare versie (concept)
export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata[ID]); // module laden
return moduleExports[metadata[NAME]]; // client‑input direct gebruiken
}
metadata[ID]: welke module geladen moet wordenmetadata[NAME]: welke export van die module
Hier wordt metadata[NAME] zonder validatie gebruikt. Als een aanvaller dit verandert naar __proto__, constructor, etc., kan hij de prototype‑keten manipuleren.
2. Prototype‑pollutie → RCE
- Wanneer de server een “normaal” object maakt, worden de vervuilde
Object.prototype‑eigenschappen overgenomen. - Als er een shell‑uitvoeringslogica (bijv.
spawnSync('sh')) aanwezig is, kan de aanvaller via het nieuwe object code laten uitvoeren. - Met één HTTP‑aanvraag kan hij dus RCE bereiken.
Wat is er precies gepatcht?
De patch van React richt zich op het verplichten van het niet vertrouwen van client‑gegeven. De belangrijkste wijziging is in de requireModule‑functie.
// Gepatchte versie (concept)
export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata[ID]);
// 👇 Controleer of NAME een eigen eigenschap is
if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
return moduleExports[metadata[NAME]];
}
return undefined as any;
}
Met deze wijziging:
- Sleutels zoals
__proto__,constructorzijn geen eigen eigenschap, dus worden geblokkeerd. - De primaire aanvalsvector (prototype‑pollutie → RCE) wordt geblokkeerd.
Andere verbeteringen omvatten:
- Versterkte validatie van Flight‑payload‑structuur
- Beperking van gevaarlijke velden
- Extra defensieve logica in gerelateerde code‑paden
Next.js en de structurele botsing
React was oorspronkelijk een UI‑bibliotheek voor de browser. Met RSC en Server Actions is het echter niet meer alleen browser‑gericht. Next.js integreert deze functies en maakt een client‑component + server‑component + server‑action ervaring.
Dit heeft geleid tot een structurele botsing:
- De server kan nu direct reageren op data die door de client wordt gestuurd, inclusief module‑laden en code‑uitvoering.
- Het beveiligingsmodel dat voor front‑end was ontworpen, past niet meer op de server.
Front‑end aannames op de server
In front‑end omgevingen:
- Bundels zijn statisch en onveranderlijk.
- Module‑laden gebeurt op build‑tijd.
- Runtime‑veranderingen van module‑namen of export‑namen zijn zeldzaam.
Daarom lijkt moduleExports[userInput] minder riskant. Op de server is het anders:
- Input is altijd onbetrouwbaar netwerkdata.
- Module‑laden en object‑creatie hebben directe toegang tot server‑resources.
- Elke vorm van deserialisatie of dynamisch laden met gebruikersinput is een RCE‑kans.
Een nieuw beveiligingsmodel had nodig:
- Strikte schema‑validatie voor Flight‑payloads.
- White‑list‑gebaseerde toegang tot client‑controleerbare waarden.
- Handtekening/Integriteitscontrole (bijv. HMAC).
- Ontwerpen met de aanname dat RSC altijd onbetrouwbare input ontvangt.
Conclusie: wanneer front‑end en back‑end grenzen vervagen, moet het beveiligingsmodel opnieuw worden ontworpen
De React/Next.js‑kwetsbaarheid is niet zomaar een bug; het toont aan dat het uitbreiden van een front‑end bibliotheek naar server‑uitvoering de bestaande vertrouwensmodellen ondermijnt.
In traditionele React + DRF/FastAPI architecturen, waar React alleen in de browser draait en de server alleen een HTTP‑API is, bestaat er geen pad voor deze kwetsbaarheid.
In Next.js, waar React‑serialisatie en deserialisatie diep in de server‑runtime zijn geïntegreerd, moet naast functionaliteit en DX ook een nieuw beveiligingsmodel en validatie‑mechanismen worden ontworpen.
De toekomst zal blijven zien dat front‑end en back‑end grenzen vervagen. Deze gebeurtenis is een waarschuwing dat gemak en beveiliging hand in hand moeten gaan.
댓글이 없습니다.