
Breve discussione sull'analisi della vulnerabilità RCE di React Server Components
Negli ultimi giorni, c'è stato un gran parlare di una vulnerabilità RCE di deserializzazione in React, con il CVSS ufficiale che ha raggiunto il massimo di 10.0, alla pari del Log4j di qualche anno fa. Immediatamente si sono diffuse voci che la definivano il "Log4j del moderno frontend", provocando il panico tra gli sviluppatori di molte aziende. Così, al risveglio, tutti si sono messi a cercare documentazione e ad applicare patch... Nel frattempo, sono emerse anche molte voci di dissenso online; alcuni, dopo aver testato la vulnerabilità, hanno scoperto che non era così grave come descritto e che, al contrario, lo sfruttamento richiedeva determinate condizioni. Ho quindi deciso di approfondire la questione e studiare questa vulnerabilità.
react-server-dom-webpack < 19.2.0, react-server-dom-turbopack < 19.2.0La vulnerabilità è causata da quanto segue: in [email protected], la funzione chiave per l'analisi delle Server Action lato server è requireModule (pseudocodice):
function requireModule(metadata) {
var moduleExports = __webpack_require__(metadata[0]);
// ...
return "*" === metadata[2]
? moduleExports
: "" === metadata[2]
? moduleExports.__esModule
? moduleExports.default
: moduleExports
: moduleExports[metadata[2]]; // ← Punto vulnerabile
}
Il cuore del problema è la parte moduleExports[metadata[2]], che non esegue alcuna validazione su metadata[2]. Ciò consente a un attaccante non solo di accedere alle proprietà esportate dal modulo stesso, ma anche a quelle presenti nella catena dei prototipi (come constructor, __proto__, ecc.). Quando un attaccante costruisce metadata[0] (ad esempio puntandolo a vm), può quindi costruire ulteriormente metadata[2] per esportare metodi pericolosi dal modulo specificato, come vm.runInThisContext, portando allo sfruttamento della vulnerabilità.
Durante la mia analisi, ho fatto riferimento all'ambiente di test e allo sfruttamento forniti da ejpir, utilizzando come esempio la gadget Code Execution vm_runInThisContext. Il processo è il seguente (nota: in un ambiente reale lo sfruttamento potrebbe differire leggermente!):
Innanzitutto, dopo aver inviato una richiesta con il payload, impostare un breakpoint per catturare la richiesta nella posizione indicata:


Successivamente, il programma esegue const formData = parseMultipart(buffer, boundaryMatch[1]);. Entrare in parseMultipart:

parseMultipart estrae i dati del corpo della richiesta e li restituisce a formData:

Entrare in const actionFn = await decodeAction(formData, serverManifest); Posizione in cui si genera la vulnerabilità:

Entrare in loadServerReference:


Ecco la posizione del codice principale che causa la vulnerabilità: requireModule. Entrare in:


Restituisce il valore di id dividendo per #: la parte prima di # come modulo, quella dopo come metodo, e il parametro bound come argomento del metodo:




Entrare in actionFn per eseguire il payload finale:



A questo punto, lo sfruttamento è concluso!
Questa vulnerabilità è ancora una volta causata da una validazione insufficiente degli input, proprio come Log4j e fastjson. Nel test sopra ho utilizzato vm_runInThisContext, ma in realtà ci sono diverse gadget sfruttabili, come ad esempio:
vm#runInThisContextvm#runInNewContextchild_process#execSyncchild_process#execFileSyncchild_process#spawnSyncfs#readFileSyncfs#writeFileSync#constructor#__proto__#prototypeUn attaccante può sfruttare questa vulnerabilità per:
vm#runInThisContext o child_process#execSync eseguire comandi arbitrari di sistemafs#readFileSync, fs#writeFileSync leggere/scrivere file arbitrari.bashrc, sovrascrivere file dell'applicazione, ecc..env, chiavi private, credenziali del database, ecc.)Sulla base di ciò, si possono proporre le seguenti misure difensive:
Le difese temporanee possono essere implementate da queste prospettive: configurare regole di blocco per questi campi pericolosi su WAF per intercettare tempestivamente attacchi malevoli. Inoltre, si può effettuare un blocco su nginx, come segue:
# Esempio di configurazione Nginx
location /formaction {
# Blocca richieste contenenti riferimenti a moduli pericolosi
if ($request_body ~* "(vm#|child_process#|fs#|module#)") {
return 403;
}
# Blocca tentativi di inquinamento della catena dei prototipi
if ($request_body ~* "(#constructor|#__proto__|#prototype)") {
return 403;
}
}
Al momento, la versione ufficiale ha già rilasciato aggiornamenti di sicurezza. Aggiornare immediatamente alle versioni sicure!:
# Aggiornare react-server-dom-webpack
npm install react-server-dom-webpack@>=19.2.0
# Aggiornare react-server-dom-turbopack
npm install react-server-dom-turbopack@>=19.2.0
# Per utenti Next.js
npm install next@>=15.0.5
Versioni corrette:
react-server-dom-webpack: >= 19.2.0react-server-dom-turbopack: >= 19.2.0next.js: >= 15.0.5Durante l'analisi della vulnerabilità sopra descritta, ho fatto riferimento all'exploit di whiteov3rflow e ho scritto ulteriormente uno strumento di rilevamento per l'ambiente di test, che ho inserito in un repository GitHub:

Chi ha bisogno di auto-ispezionarsi può visitare il repository per ottenerlo (nota: a causa dell'ambiente di test dell'autore originale, al momento potrebbe essere adatto solo per quell'ambiente specifico; in futuro verrà migliorato. Chi ne ha bisogno può anche modificarlo da sé...). Attenzione: utilizzare solo con autorizzazione legale, è vietato utilizzarlo per attività non autorizzate!
Ad oggi, 5 dicembre 2025, la situazione online è che il "rumore" su questa vulnerabilità va su e giù come sulle montagne russe: a volte viene considerata una "bomba nucleare", a volte una "falla innocua", e poco dopo torna a essere una "bomba nucleare"... I metodi di sfruttamento sono sempre più numerosi. Secondo le informazioni attuali, è probabile che la "bomba nucleare" venga confermata, ma con un impatto più limitato rispetto a Log4j. In ogni caso, tutti i soggetti coinvolti dovrebbero aggiornare il prima possibile per eliminare eventuali rischi futuri!!!
Inoltre, un consiglio di sicurezza per gli sviluppatori: non fidatevi mai dell'input dell'utente. Log4j, fastjson e ora React RCE sono caduti per lo stesso motivo. Pertanto, nello sviluppo reale, per le posizioni pericolose è necessario utilizzare sandbox o whitelist per una validazione rigorosa, evitando così tragedie!!!
Ciò che si legge sulla carta sembra superficiale, ma per capire veramente la questione è necessario agire con cautela.