Vulnerabilidad RCE de React (CVE-2025-55182) – Problemas y causas
La vulnerabilidad de React Server Components (CVE-2025-55182, también conocida como React2Shell / React4Shell) revelada a principios de diciembre de 2025 tiene un CVSS de 10.0 y permite la ejecución remota de código (RCE) sin autenticación previa. Se han observado PoC publicados y intentos reales de escaneo y ataque.
Este artículo ofrece una versión más estructurada de “quién, por qué y hasta dónde es peligroso”.
Resumen rápido
-
Causa principal La vulnerabilidad se debe a un fallo en la lógica de deserialización del protocolo Flight que utilizan los React Server Components (RSC). Un atacante puede enviar una solicitud manipulada y hacer que el servidor ejecute código JavaScript arbitrario.
-
Componentes principales afectados
-
react-server-dom-webpack / -parcel / -turbopack19.0 / 19.1.0 / 19.1.1 / 19.2.0 -
Los Next.js que los incluyen: Next.js 15.x, 16.x, 14.3.0-canary.77 en adelante (cuando se usa App Router)
-
Aplicaciones puramente en el navegador Las apps React SPA que no usan RSC/Server Actions o renderizado del servidor no se ven afectadas.
-
Pasos inmediatos para usuarios de Next.js
- Verifica las versiones de
react-server-dom-*ynexten tu proyecto. - Actualiza React a 19.0.1 / 19.1.2 / 19.2.1 o superior.
- Actualiza Next.js a las versiones parcheadas (15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7, etc.) o baja a una versión estable.
- Si tu servidor ya está expuesto a Internet, revisa logs, reglas WAF y cualquier anomalía.

¿Qué es exactamente la vulnerabilidad?
Según la información publicada por el equipo de React, la vulnerabilidad se resume así:
- Objetivo: Implementaciones de React Server Components (
react-server-dom-*). - Alcance: Lógica de deserialización (decodificación) del protocolo Flight utilizada al enviar datos RSC del cliente al servidor.
- Método de ataque:
- El atacante envía un payload Flight manipulado a los endpoints HTTP de RSC/Server Actions.
- El servidor “confía” en esos datos y, al deserializarlos, permite que la lógica de carga de módulos/creación de objetos sea dirigida por la entrada del atacante.
- Como resultado, se puede ejecutar código arbitrario en el entorno del servidor.
Lo importante es que el ataque es sin autenticación. Un servidor Next.js RSC expuesto a Internet es vulnerable desde el momento en que está accesible.
Condiciones exactas para que la vulnerabilidad se active
1. Condiciones de versión de React/Next.js
- Paquetes relacionados con RSC
react-server-dom-webpackreact-server-dom-parcel-
react-server-dom-turbopack -
Versiones vulnerables
-
19.0, 19.1.0, 19.1.1, 19.2.0
-
Versiones parcheadas
-
19.0.1, 19.1.2, 19.2.1
-
Next.js (basado en App Router)
- Vulnerable:
- 14.3.0-canary.77 y superiores
- 15.x, 16.x (estructura App Router que incluye RSC)
- Parcheado:
- 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7, etc.
2. Condiciones de arquitectura/entorno
La vulnerabilidad es más probable cuando se cumplen todas las siguientes condiciones:
-
Uso de RSC * Next.js App Router o cualquier framework que soporte RSC.
-
Ejecución de código React en el servidor * Node.js u otro entorno donde RSC/Server Actions se ejecuten.
-
Servidor expuesto a HTTP * Accesible desde Internet o desde la red interna.
En cambio, los siguientes entornos son prácticamente irrelevantes:
- SPA React puro basada en CRA/Vite.
- Uso de RSC/Server Actions sin publicar, solo bundles estáticos en S3/CDN.
- Arquitecturas donde React solo corre en el navegador y el servidor es una API separada (ej. React + Django REST, React + FastAPI).
¿Por qué la combinación React‑DRF o React‑FastAPI era relativamente segura?
Cuando React se combina con back‑ends como Django REST Framework o FastAPI, no se produce el problema porque:
-
React no se ejecuta en el servidor * React corre solo en el navegador; Django/FastAPI solo sirven APIs HTTP. * El servidor no necesita entender el protocolo Flight ni interpretar RSC.
-
Frontera de comunicación clara * La comunicación React ↔ servidor se hace vía JSON/HTTP API. * El servidor no
require()módulos de React ni cargametadataenviado por el cliente. -
No se usan RSC/Server Actions/Flight * El vector de ataque depende de la lógica de deserialización de Flight en el servidor. * Django/FastAPI no incluyen ese código.
En resumen, la vulnerabilidad es un problema estructural que solo aparece cuando React y el servidor están integrados (Next.js, etc.). Las arquitecturas con React SPA + API REST no tienen la ruta de código vulnerable.
Protocolo Flight y contaminación de prototipos en el servidor
A nivel técnico, la vulnerabilidad sigue el flujo típico: deserialización de Flight → contaminación de prototipos → RCE.
1. Patrón de código problemático
El concepto de la función vulnerable es algo así (ejemplo conceptual):
// Versión vulnerable (concepto)
export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata[ID]); // carga de módulo
return moduleExports[metadata[NAME]]; // usa entrada del cliente sin validar
}
metadata[ID]: identifica qué módulo cargar.metadata[NAME]: indica qué export del módulo usar.
El problema es que metadata[NAME] se usa sin ninguna validación. Si un atacante cambia este valor a __proto__, constructor, etc., puede manipular la cadena de prototipos del objeto.
2. Contaminación de prototipos → RCE
- Cuando el servidor crea un objeto “normal”, las propiedades contaminadas de
Object.prototypese heredan. - Si dentro de ese objeto hay lógica que ejecuta
spawnSync('sh')u otro comando shell, el atacante puede hacer que se ejecute a través de la cadena de prototipos. - Así, con una sola solicitud HTTP, se logra RCE.
¿Qué se parcheó exactamente?
El parche de React se centra en no confiar en los valores enviados por el cliente. La función requireModule es el cambio clave.
// Versión parcheada (concepto)
export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata[ID]);
// 👇 Verifica que el NAME sea una propia propiedad del módulo
if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
return moduleExports[metadata[NAME]];
}
return undefined as any;
}
Con esta línea, claves como __proto__ o constructor (que no son propias) quedan bloqueadas, eliminando el vector de ataque.
El parche también incluye:
- Validación más estricta de la estructura del payload Flight.
- Restricción de campos potencialmente peligrosos.
- Lógica defensiva adicional en rutas de código relacionadas.
En esencia, la adición de validaciones es el núcleo del parche.
Conflictos estructurales al expandir React al servidor
Originalmente, React era una librería de UI que se ejecutaba en el navegador. Con RSC y Server Actions, React ya no es solo cliente.
Next.js integró estas características para ofrecer:
- Componentes cliente + servidor + acciones de servidor en una sola app.
- Permitiendo que los datos enviados por el cliente puedan influir directamente en la carga de módulos y la ejecución de código en el servidor.
Esto alteró el modelo de seguridad.
Problema de trasladar supuestos de front‑end al back‑end
En el front‑end, normalmente:
- Los bundles son estáticos e inmutables.
- La carga de módulos se decide en tiempo de compilación.
- Los usuarios no cambian nombres de módulos o exportes.
Por eso, patrones como moduleExports[userInput] parecen menos riesgosos.
En el back‑end, la situación es distinta:
- La entrada proviene de la red y es inherentemente no confiable.
- La carga dinámica de módulos y la creación de objetos están vinculadas a recursos del servidor.
- Mezclar deserialización y carga dinámica con entrada del usuario siempre abre la puerta a RCE.
Se necesitaba un nuevo modelo de seguridad:
- Validación estricta de la estructura del payload Flight.
- Acceso basado en listas blancas a valores controlables por el cliente.
- Firma de integridad (HMAC) o similar.
- Diseñar con la premisa de que RSC siempre recibe entrada no confiable.
El modelo tradicional de React (solo front‑end) se trasladó al servidor sin ajustes, revelando la vulnerabilidad.
Conclusión: Rediseñar el modelo de seguridad cuando la frontera front‑end/back‑end se difumina
Esta vulnerabilidad de React/Next.js demuestra que:
- Cuando una librería de front‑end se expande a la ejecución en el servidor, el modelo de confianza de front‑end ya no es válido.
- Arquitecturas tradicionales como React + DRF/FastAPI, donde React solo corre en el navegador y el servidor solo expone APIs, no presentan este vector.
- En entornos donde React y el servidor están integrados (Next.js), se debe diseñar un modelo de seguridad y validación desde el principio.
El futuro traerá más frameworks que borren la frontera entre front‑end y back‑end. Este incidente subraya la necesidad de priorizar la seguridad y la definición clara de modelos de confianza antes de buscar conveniencia y DX.
No hay comentarios.