Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2025-55182 | Kitploit
Herramientas/GitHubGitHub/topstar88/cve-2025-55182
Análisis de VulnerabilidadesAnálisis de CódigoExplotaciónExplotación de Aplicaciones WebAprendizaje y EducaciónDesarrollo de Payloads
GitHubtopstar88/cve-2025-55182

CVE-2025-55182

Ver Repositorio
hace 8 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2025-55182

Este repositorio contiene una reproducción PoC de CVE-2025-55182, una vulnerabilidad de seguridad crítica en React Server Components (RSC) que permite la ejecución arbitraria de código sin autenticación.

Descripción

La vulnerabilidad existe en la forma en que React Server Components deserializa las "Server Actions" de las peticiones del cliente. En concreto, la función requireModule no validaba que el nombre de exportación solicitado fuera una propiedad directa del módulo. Esto permitía a los atacantes acceder a la propiedad constructor de las funciones exportadas, obteniendo una referencia al constructor global Function, que puede utilizarse para ejecutar código arbitrario.

Reproducción

Este PoC utiliza un entorno Node.js mínimo para aislar la vulnerabilidad en la librería react-server-dom-webpack, solo para asegurarse de que el exploit demuestra el fallo en la propia librería, NO una mala configuración en un framework.

Requisitos previos

  • Node.js
  • npm

Instalación

root@kitploit:~
npm install

[!NOTE] El package.json está fijado a la versión vulnerable 19.0.0.

Prueba de concepto

  1. Inicia el servidor vulnerable

Este script configura un servidor HTTP básico que utiliza el runtime de React vulnerable para decodificar las peticiones.

root@kitploit:~
# tty1
node --conditions react-server server.js
  1. Ejecuta el script del exploit

En una terminal separada, ejecuta el exploit. Esto envía un payload Flight malicioso al servidor.

root@kitploit:~
# tty2
node exploit.js id

Deberías ver la salida del comando devuelta en la respuesta:

Salida esperada:

root@kitploit:~
Response: uid=0(root) gid=0(root) groups=0(root)

Análisis

¿Por qué ocurrió la vulnerabilidad?

La función requireModule en ReactFlightDOMServerNode.js básicamente confiaba en cualquier name que enviara el cliente. Hacía moduleExports[metadata[NAME]] sin comprobar si esa propiedad realmente debía estar expuesta. Así que si el cliente decía «oye, quiero esta propiedad», el servidor respondía «¡claro! ahí la tienes, amigo».

¿Por qué es mala idea permitir que la gente acceda a cualquier propiedad?

Porque básicamente permite que cualquiera acceda a la cadena de prototipos, incluso al constructor, lo cual es super peligroso. Si el módulo exporta una función (como module.exports = () => {}), entonces su constructor es literalmente el constructor global Function.

¿Por qué obtener el constructor Function implica RCE?

Una vez que un atacante obtiene el constructor Function, puede abusar de la funcionalidad "Bound Server Action". Le vinculan una cadena que contiene JavaScript malicioso (básicamente convirtiéndolo en new Function("evil code")). Y una vez que se ejecuta, el servidor ejecuta cualquier código que hayan introducido.

¿Por qué React ejecutaría realmente esa función maliciosa?

Porque las Server Actions pueden activarse mediante un ID. Si el atacante crea un payload con un Action ID que apunte a su referencia module#constructor, React lo resuelve como una acción normal y lo ejecuta. Esa «acción» es en realidad su función maliciosa.

¿Por qué no se validó nada de esto?

El sistema simplemente asumía que id y name de los metadatos de Server Reference siempre harían referencia a exportaciones válidas definidas por el desarrollador. No había ninguna comprobación de seguridad como hasOwnProperty para asegurarse de que la propiedad solicitada fuera una exportación real y no algo heredado de la cadena de prototipos.

¿Por qué server.js en lugar de Next.js?

Utilizo un server.js básico (y un helper webpack-runtime.js) para configurar manualmente el runtime de React Server Components. Esto nos permite:

  1. Forzar la configuración vulnerable: El exploit solo funciona si un módulo se exporta como función (module.exports = fn). Un bundler real podría cambiar cómo se envuelven las exportaciones, dependiendo de su configuración.
  2. Aislar el fallo: Esto nos permite demostrar que el problema está dentro de react-server-dom-webpack, no en Next.js.
  3. Recrear el entorno del bundler: react-server-dom-webpack asume que se ejecuta dentro de un bundle de Webpack. Nuestro webpack-runtime.js le proporciona los globales que espera (__webpack_require__, __webpack_chunk_load__).

Esto no es simular la vulnerabilidad, es simplemente darle a la librería el runtime mínimo necesario para que realmente funcione.

Notas

Ha habido discusión sobre "PoCs inválidos" que solo funcionan si el desarrollador expone deliberadamente cosas peligrosas como child_process.exec.

Este PoC no es uno de esos. Funciona en una configuración normal y segura.

  1. La función expuesta es inofensiva La aplicación expone una función simple updateProfile que solo devuelve una cadena y nada sospechoso, sin comandos de shell.

  2. El exploit escapa completamente de esa función La vulnerabilidad permite al atacante ignorar la exportación segura e ir directamente a updateProfile.constructor, que es el constructor global Function.

  3. El problema central es el acceso a la propiedad React NO debería haber permitido el acceso a .constructor. El desarrollador no tenía la intención de exponer el constructor Function; en cambio, la deserialización insegura lo hizo por él.

El único requisito real es que el módulo exporte una función directamente (module.exports = fn), algo muy común en CommonJS y en muchas configuraciones de bundlers.

El Payload

El payload en exploit.js construye un mensaje React Flight con tres chunks:

  • Chunk 0: Apunta a una Server Reference definida en el Chunk 1.
  • Chunk 1: Declara la Server Reference:
    • id: "user-profile-action#constructor", es decir, «dame el constructor».
    • bound: apunta al Chunk 2, que contiene los argumentos.
  • Chunk 2: ["console.log('nice try, diddy!')"]: la cadena de código malicioso.

Cuando React deserializa esto:

  1. Resuelve user-profile-action.
  2. Lee la propiedad .constructor => obtiene el Function global.
  3. Vincula la cadena proporcionada por el atacante.
  4. Ejecuta efectivamente: new Function("console.log('nice try, diddy!')")

¡Y eso es el RCE!

Mitigación

Actualiza inmediatamente a las versiones parcheadas:

  • react-server-dom-webpack >= 19.0.1
  • react-server-dom-parcel >= 19.0.1
  • react-server-dom-turbopack >= 19.0.1

El parche introduce comprobaciones hasOwnProperty para evitar el acceso a propiedades heredadas y restringe la subida de archivos base64.

Si ejecutas este PoC contra una versión parcheada, el servidor fallará o dará un error como:

root@kitploit:~
$ node --conditions react-server server.js
Listening on http://localhost:3000
/path/to/CVE-2025-55182/node_modules/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js:2726
            resolvedValue = resolvedValue.bind.apply(
                                          ^

TypeError: Cannot read properties of undefined (reading 'bind')
    at /path/to/CVE-2025-55182/node_modules/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js:2726:43
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v20.19.3

Esto confirma que el exploit no pudo acceder a la propiedad constructor (devolvió undefined en lugar de Function), por lo que la posterior llamada a .bind falló.

Aviso legal

Este código es solo para fines educativos y de prueba. No utilices este exploit contra sistemas que no poseas o para los que no tengas permiso explícito de prueba.

Licencia

Publicado bajo la DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE.

Descargar herramienta