Para: cualquiera que despliegue apps con Next.js (o frameworks JS similares), especialmente «lo construí con ayuda de IA, operando a ojo». Destilado de un incidente real (→ el CVSS 10.0 descuidado).
La visión de este sitio: lo que importa no es la velocidad sino un sistema que no pase nada por alto
Cuando los desarrolladores indie se quedan cortos en seguridad, normalmente no es por falta de conocimiento sino porque no consiguen mantener la operación. Leer las noticias de CVE más rápido que nadie no tiene valor (deja la velocidad a los proveedores y a las noticias). Lo que funciona es un sistema que no se perderá los CVE relevantes para ti. Así que este artículo se centra en construir ese sistema más que en saber más.
1. Juzga por la versión en ejecución
Mide «¿estoy en una versión peligrosa?» por lo que está realmente en ejecución, no por el piso del manifiesto — porque el número del manifiesto y la versión en ejecución a menudo discrepan.
✗ Contar por el piso de package.json
"next": "^16.0.0" → «16.0.0 es vulnerable, así que nosotros también» — sobrecontado como «8 vulnerables».
✓ Contar por la versión en ejecución
npm ls next muestra la versión resuelta → las autoincrementadas están a salvo, solo las fijadas se quedan atrás. Realmente 2.
# see the versions actually resolved
npm ls next react react-dom
# inside a running container
docker exec <container> npm ls nextLos rangos con caret (^16.0.0) se autoincrementan al reconstruir; las dependencias fijadas se quedan atrás. Juzga por las versiones que aparecen aquí.
Cómo comprobar tu propia configuración
Estos pasos te dicen qué versión ejecuta realmente tu app y si le afecta un CVE conocido. Cada uno solo inspecciona tu propio entorno.
Comprueba la versión local
Ejecuta npx next info en la carpeta del proyecto. Muestra las versiones reales de next, react y react-dom, y cuánto te separa de la última versión. npx next -v muestra solo la versión de Next.js.
Mira por qué tienes esa versión
npm ls next (o pnpm why next) muestra qué versión está instalada y a través de qué paquete. Si tu lockfile (package-lock.json o pnpm-lock.yaml) no está en el repositorio, la versión puede cambiar en cada build, así que súbelo primero.
Comprueba la versión en ejecución en producción
Actualizar en local no cambia un servidor que sigue ejecutando una imagen antigua. En un contenedor, lee el campo version del package.json de next dentro del contenedor en ejecución (comando más abajo). Esto también funciona con output: 'standalone'.
Cruza con los CVE conocidos
npm audit --omit=dev revisa solo las dependencias que van a producción. Añadir --audit-level=high hace que termine con un código distinto de cero cuando encuentra algo High o superior, así que el CI puede detenerse ahí. Escanear el lockfile con osv-scanner sirve para lo mismo.
Lee el aviso oficial para tu configuración
Los avisos de Next.js a veces distinguen entre App Router y Pages Router, o entre autoalojado y gestionado. Compara las versiones corregidas que indica el aviso con las versiones que encontraste en los pasos 1 a 3.
# local: actual versions and distance from latest
npx next info
# the version running inside the production container
docker exec <container> node -p "require('next/package.json').version"
# check only production dependencies; fail on High or above
npm audit --omit=dev --audit-level=highQué cambia según cómo lo ejecutes
El mismo CVE puede afectarte o no según cómo ejecutes Next.js. Dos casos pasados, por tipo de despliegue:
| Cómo lo ejecutas | Bypass de autorización del middleware (CVE-2025-29927) | RCE de RSC (CVE-2025-55182) | Quién actualiza |
|---|---|---|---|
| Gestionado (Vercel, Netlify, etc.) | No afectado (el enrutado se ejecuta en un sistema aparte) | Afectado si usas App Router; hay reglas de bloqueo, pero aun así debes actualizar | Tú (tu lockfile decide la siguiente versión) |
| Autoalojado (next start / standalone, incl. Docker) | Afectado | Afectado si usas App Router | Tú (reconstruyendo la imagen y reiniciando) |
| Exportación estática (output: 'export') | No afectado (no se ejecuta ningún servidor) | Ningún servidor recibe peticiones, así que en general no te alcanza | Tú (las dependencias de build también necesitan actualizarse) |
Así que, incluso con alojamiento gestionado, subir la versión de Next.js es trabajo tuyo. Trata las protecciones del proveedor como tiempo ganado hasta que estés en la versión parcheada.
Comprueba también el periodo de soporte. Según la política de soporte oficial, a octubre de 2026:
| Línea | Estado (octubre de 2026) | Correcciones de seguridad |
|---|---|---|
| 16.x | Active LTS (funciones, correcciones, parches de seguridad) | Sí |
| 15.x | Maintenance LTS (dos años desde la publicación inicial) | Solo las críticas |
| 14.x y anteriores | Sin soporte | En raras ocasiones, para problemas graves, sin garantía |
2. Monitorea tus dependencias automáticamente
Rastrear CVE a mano no se sostiene, y el descuido se convierte en el incidente. Monitoréalas automáticamente con una herramienta.
Monitoreo gratuito de dependencias
osv-scanner scan -L pnpm-lock.yamlEn GitHub, activa Dependabot (en el repositorio: Settings → Advanced Security → Dependabot alerts). Recibirás PRs solo para los CVE que coincidan con tus dependencias.
Lo que importa es la priorización. La postura de este sitio: clasifica por «¿está siendo explotado (KEV)?» por «¿qué tan alto es el CVSS?». Un CVSS alto que no usas es de bajo impacto; una puntuación media bajo explotación activa es máxima prioridad. Esa priorización es el núcleo del trabajo.
3. Actualizar: pasa a la versión corregida, no a una solución provisional
Cuando aparece una vulnerabilidad, actualiza el framework a la versión parcheada para corregir la vulnerabilidad en sí.
Arreglos superficiales (insuficiente)
- Bloquear solo las peticiones que parecen el ataque en un proxy inverso
- Detener los cargos/el síntoma y llamarlo «resuelto»
- Dejar en su sitio la vulnerabilidad de RCE en sí
Corregir la causa (correcto)
- Actualizar el framework a la versión parcheada
- Tras actualizar, confirmar que la firma desaparece en tus registros
- Tratar el frenar el daño y el corregir la causa como dos trabajos distintos, y hacer ambos
El fallo común
«Detuve los cargos/el síntoma» ≠ «resuelto». Frenar el daño y corregir la vulnerabilidad son trabajos distintos. Haz ambos.
Un caso real: la vulnerabilidad de React Server Components de diciembre de 2025
Así fue en la práctica gestionar un CVE publicado, tomando como ejemplo la vulnerabilidad de React Server Components (RSC) divulgada en diciembre de 2025. Todo lo que sigue procede de los anuncios oficiales de React y Next.js y de los datos públicos de CISA.
3 de diciembre de 2025
React divulgó CVE-2025-55182 (CVSS 10.0), que puede llevar a la ejecución de código en el servidor sin autenticación. En Next.js, las apps con App Router en 15.x, 16.x y algunas canary estaban afectadas (CVE-2025-66478); Pages Router y Edge Runtime no. No había solución provisional: era necesario actualizar a una versión corregida (15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7, entre otras).5 de diciembre de 2025
CISA la añadió a su catálogo de vulnerabilidades con explotación confirmada (KEV).6 de diciembre de 2025
Next.js añadió que las apps que estuvieran en línea y sin parchear a las 13:00 (hora del Pacífico) del 4 de diciembre debían rotar los secretos que usan (claves de API, etc.).11 de diciembre de 2025
Mientras se examinaba el parche, se encontraron y corrigieron dos problemas más en el mismo mecanismo (denegación de servicio y exposición del código fuente). Después, la corrección de la denegación de servicio resultó incompleta, se emitió CVE-2025-67779 y se pidió a quienes ya habían actualizado que volvieran a actualizar.
De aquí salen tres lecciones operativas:
- Una actualización no es el final. Pueden llegar correcciones posteriores del mismo código con días de diferencia
- Las reglas de bloqueo del proveedor eran un complemento; actualizar se describió como la única solución completa
- Si estuviste en línea antes de parchear, rota los secretos además de actualizar
La visión de este sitio: «hecho» significa que la versión de producción está parcheada, no que ejecutaste una actualización
Cuando siguen llegando correcciones, como aquí, «actualicé la semana pasada» deja de ser fiable. Juzga si está terminado por si la versión en ejecución en producción es igual o superior a la versión corregida del último aviso, no por el recuerdo del trabajo hecho. Este sitio también da una actualización por terminada solo después de confirmar que el contenedor se recreó y de comprobar la versión que se ejecuta dentro.
Errores frecuentes y cómo corregirlos
- Juzgar por el número de package.json: la versión instalada puede ser otra. Compruébalo con
npx next infoonpm ls next. - Quedarse en actualizar el lockfile: la versión antigua sigue ejecutándose hasta que se reconstruye y reinicia la imagen de producción. Comprueba la versión dentro de producción.
- Sentirse a salvo tras una actualización: pueden llegar avisos posteriores. Mantén activas las alertas de Dependabot o similares y vigila los avisos durante unos días.
- Dejarlo en manos de las reglas de bloqueo del proveedor: puede que no frenen todas las formas de un ataque. Actualiza.
- Quedarse en una línea sin soporte: 14.x y anteriores no tienen garantía de correcciones. Planifica el paso a 16.x.
- Perder entre el ruido de desarrollo los avisos que afectan a producción: ejecuta
npm audit --omit=devpara ver primero lo que va a producción. - Ignorar el periodo antes de parchear: pudieron robar secretos en ese tiempo. Rota las claves de API y las contraseñas de la base de datos (→ fundamentos de .env y claves de API).
4. Mínimo privilegio para limitar el daño
Diséñalo para que el daño quede limitado si explotan la app.
Ejecuta como usuario sin privilegios
USER del contenedor como root. Así una brecha solo alcanza lo que ese usuario puede hacer.Vincula BD/Redis solo a la red interna
Separa por servicio
Estas deciden si una brecha se detiene en «robo de entorno dentro de un contenedor» o llega a «toma de control del host».
Esto lo hacemos nosotros mismos
Este sitio monitorea sus propias dependencias en busca de CVE, exactamente como se escribe aquí — para que el tipo de descuido que lo empezó todo (un CVSS 10.0 público descuidado) no vuelva a depender de la atención humana. Decimos «clasifica por prioridad (KEV + CVSS)» porque así operamos de verdad.
Leer a continuación
- Incidente: un RCE público descuidado facturado de forma fraudulenta
- Glosario: CVE · CVSS · RCE
- Historia: Log4Shell — RCE a través de una dependencia
- Por framework: seguridad de Next.js (frontera servidor/cliente, variables de entorno, CVE de dependencias)
- Priorizar: ordenar los CVE con CVSS, EPSS y KEV
- Monitoreo: configurar osv-scanner
- El panorama: ¿tienen Next.js y React muchas vulnerabilidades? (en inglés; lo que muestran de verdad los datos de CVE)
Fuentes
- Next.js, "Security Advisory: CVE-2025-66478" (3 de diciembre de 2025; actualizado el 6 de diciembre): nextjs.org
- Next.js, "Security Update: December 11, 2025" (CVE-2025-55183 / 55184 / 67779): nextjs.org
- NVD, "CVE-2025-55182": nvd.nist.gov / CISA, "Known Exploited Vulnerabilities Catalog": cisa.gov
- Vercel, "React2Shell Security Bulletin": vercel.com
- Vercel, "Postmortem on Next.js Middleware bypass" (CVE-2025-29927): vercel.com
- Next.js, "Support Policy": nextjs.org / "next CLI": nextjs.org / "Static Exports": nextjs.org
- npm Docs, "npm audit": docs.npmjs.com / OSV-Scanner, "Usage": google.github.io / GitHub Docs, "Configuring Dependabot alerts": docs.github.com