El 25 de octubre de 2026 audité los siete sitios Next.js que alojo yo mismo, y seis eran vulnerables. El portfolio que estás leyendo estaba en la 16.2.10. El motivo: una vulnerabilidad de Next.js que el equipo cerró con una versión fuera de ciclo el 14 de octubre. Dos ejecuciones remotas de código (RCE) críticas y una denegación de servicio.
Abajo cuento qué versiones están afectadas, cómo comprobar la tuya en un par de minutos, qué cambié y qué dejé como estaba. Por Instagram y LinkedIn circula un reel de seguridad con 15 identificadores, y una de sus etiquetas es incorrecta. Importa para el parche, así que empiezo por ahí.
Vulnerabilidad Next.js del 14 de octubre: qué se corrigió#
La fuente es el aviso oficial de seguridad de Next.js del 14 de octubre de 2026 y los avisos de GitHub enlazados. Las versiones corregidas son la 16.4.1 y la 15.5.28. El 25 de octubre la última en npm es la 16.4.3.
| ID | Qué | A quién afecta | Corregido en |
|---|---|---|---|
| GHSA-673q-mjm6-r5xr (sin CVE aún), CVSS v4 9.5 | RCE sin autenticación en funciones use cache que devuelven arrays tipados | 16.0.0 a 16.4.0, App Router con Cache Components y una función use cache que devuelve varios arrays tipados | 16.4.1 (la 15.x no figura) |
| GHSA-2464-fhr4-w9xw, CVE upstream CVE-2026-96889, CVSS v4 9.5 | RCE sin autenticación en la API de Image Optimization al procesar SVG | 10.0.0 a 15.5.27 y 16.0.0 a 16.4.0, en Linux con glibc | 15.5.28 y 16.4.1 |
| GHSA-p3m5-59mp-jv5r, CVE-2026-94482, CVSS v4 8.2 | Denegación de servicio en App Router con Server Actions | 13.0.0 a 15.5.27 y 16.0.0 a 16.4.0, con al menos una Server Action | 15.5.28 y 16.4.1 |
Las apps con Pages Router y sin Server Actions no se ven afectadas por la tercera. La primera y la tercera no tienen mitigación. Para la primera, Vercel recomienda actualizar aunque no tengas esa función. Eso hice.
CVE-2026-96889 no es un CVE de Next.js#
El reel lo llama "Next.js CVE-2026-96889". El registro dice otra cosa: es un use-after-free en librsvg ("xml includes have duplicated entities"), publicado el 23 de septiembre con Red Hat como CNA, CVSS v3.1 7.8. Next.js lo hereda a través de sharp, que renderiza SVG con librsvg. El aviso de sharp es GHSA-wq5f-xc86-pv6w: afecta a versiones anteriores a la 0.35.5.
¿Por qué importa la etiqueta? Porque cambia el remedio. Una medida es actualizar next; la otra, asegurarte de que sharp sea 0.35.5 o superior. Y aquí está la trampa: next@16.4.3 depende de sharp ^0.35.5, pero next@15.5.28 admite ^0.34.3 || ^0.35.5. En 15.x el lockfile puede conservar sharp 0.34.x después de actualizar. A mí me pasó exactamente eso, así que ahora fijo sharp de forma explícita.
Dos datos más antes de que cunda el pánico. Ninguno de los 15 identificadores del reel está en el catálogo CISA KEV (comprobado con la versión del 23 de octubre), y la evaluación ADP de CISA marca la explotación como "none" en todos salvo en este, que figura como "poc". "Black October" no es una campaña con nombre, sino un conjunto de avisos reales (nginx, Next.js, GitLab, PHP, Node.js, Java) que coincidieron en dos semanas. El resto de la lista lo repaso en el resumen de CVE de octubre de 2026.
Cómo comprobar la versión de Next.js y si estás expuesto#
No me fío de lo que muestra el navegador aquí. Mira el lockfile y el contenedor en marcha:
npm ls next sharp # pnpm: pnpm why next
npm view next dist-tags # qué es lo actual en npm
npm audit --omit=dev # pnpm: pnpm audit --prod
docker run --rm <image> node -v # versión de Node dentro de la imagenDespués, tres grep para ver qué aviso te toca de verdad:
grep -rn "use cache" app src # primera RCE
grep -rn "use server" app src # DoS por Server Actions
grep -n dangerouslyAllowSVG next.config.* # vía SVGSin use cache, el primer fallo no te alcanzaba, aunque conviene actualizar igual. Sin "use server", el DoS queda descartado. Y un dangerouslyAllowSVG: true en la configuración es lo que yo miraría con más atención.
Cómo actualizar: Next.js, sharp, zod y Node en Docker#
Lo que apliqué, en orden:
npm install next@16.4.3 # si estás en 16.x
npm install next@15.5.28 # si estás en 15.x
npm install sharp@^0.35.5 # fijado explícito- Next.js. 16.x a 16.4.3, 15.x a 15.5.28. Si te saltaste las actualizaciones de septiembre, acuérdate de los avisos anteriores: RCE en servidores Windows (CVE-2026-75604, corregido en 15.5.24 y 16.3.3), RCE en Image Optimization con AVIF (mismas versiones) y RCE en
next/ogImageResponse (CVE-2026-94545, corregido en 16.3.6). Saltar directo a las versiones actuales cubre todo. - sharp. Fija
^0.35.5, por lo explicado arriba. Los avisos previos de sharp (libvips en GHSA-f88m-g3jw-g9cj, libheif en GHSA-rgj7-g3m4-5g8c) quedan cubiertos con el mismo fijado. - zod. Ya que estaba en el lockfile, subí zod 4.x a 4.6.6 o superior: GHSA-mrhx-c7xc-m3w5, agotamiento de memoria con colecciones acotadas demasiado grandes.
- Node en Docker. El 21 de octubre salieron Node.js 22.23.4, 24.22.1 y 26.12.1 (publicación oficial), con cuatro de severidad alta: escritura fuera de límites en el decodificador Brotli, truncado de nombres en un carácter NUL en
dns.resolve*y dos saltos de la comprobación de hostname en TLS. Un contenedor en marcha no se actualiza solo. Hay que reconstruir la imagen. - SVG. Si ningún SVG pasa por
next/imageen tu app, devuelveimages.dangerouslyAllowSVGafalse.
Con Docker tropecé dos veces. La imagen base del portfolio estaba fijada por digest a una compilación antigua de node:22. Esa fijación congela todo, parches de seguridad incluidos, y yo no tenía un proceso para rotarla. Otro sitio seguía en node:20, fuera de soporte desde abril de 2026 y sin correcciones. Un node:22-slim flotante tampoco es seguro: la imagen puede salir de la caché del host de compilación y reconstruir no trae el parche nuevo. Lo fiable es una etiqueta explícita del espejo de AWS:
FROM public.ecr.aws/docker/library/node:22.23.4-slim AS baseUsa la variante (slim, alpine) que ya tengas. Tras la compilación, docker run --rm <image> node -v debe imprimir v22.23.4. La misma lógica vale para todo lo que alojas tú; lo toqué en el artículo sobre autoalojar ClewWiki.
Qué encontré en mis siete sitios#
Mi montaje: siete sitios Next.js en Docker en un solo servidor, desplegados con Dokploy y con Traefik delante. En ese servidor no hay nginx, PHP, Java ni GitLab, así que la mayor parte de la lista de octubre no me tocaba.
| Comprobación | Resultado el 25 de octubre |
|---|---|
| Vulnerables en la auditoría | 6 de 7 |
| Versiones halladas | 16.2.10 (portfolio), 16.3.8, 15.5.21, 15.5.22, 15.5.23, 15.5.25; uno ya en 15.5.28 |
npm audit --omit=dev en el portfolio | 12 problemas: 2 critical (next, dompurify), 8 high. Tras actualizar: 0 critical |
use cache en el código | ninguno de los 7 sitios |
| Server Actions | un sitio, así que el DoS le aplicaba |
| Imágenes base de Docker | una fijada por digest a un node:22 viejo, otra en node:20; todas movidas a node:22.23.4-* |
El hallazgo que menos me gusta está en el next.config.js del portfolio. Tenía images.dangerouslyAllowSVG: true con un CSP de sandbox, y en todo el proyecto ningún SVG había pasado nunca por next/image. Un camino abierto justo al fallo de SVG, sin ningún beneficio. Lo desactivé.
Qué queda pendiente#
Tras actualizar, los high restantes de npm audit son solo de compilación: la cadena workbox y next-pwa, y postcss dentro de next. Solo se ejecutan mientras se construye la imagen de Docker, no en el proceso del servidor, así que un atacante no tiene ruta hacia ellos en ejecución. Los dejé para el próximo ciclo de dependencias y lo digo tal cual, sin fingir un informe limpio. Queda otro hueco, y también lo cuento: el propio portfolio usa zod 3, y la corrección de zod existe solo en la 4.6.6. Sus dos esquemas validan cadenas cortas con un límite de longitud, no colecciones, así que el fallo de memoria no tiene de dónde crecer; la migración a zod 4 está en la lista. Las rutas de RCE de este lote están cerradas en los siete.
Tampoco toqué nada fuera de mi stack. Nginx 1.30.6 o 1.31.7, PHP 8.5.12 y sus ramas hermanas, GitLab y Java tienen sus propias correcciones; los detalles están en el resumen enlazado arriba.
Lista de comprobación#
npm ls next sharpmuestra next 16.4.1 o superior (la actual es la 16.4.3) o 15.5.28, y sharp 0.35.5 o superior.npm audit --omit=devno tiene critical.dangerouslyAllowSVGestá desactivado, salvo que sirvas SVG pornext/image.- zod en 4.6.6 o superior.
- El Dockerfile usa una etiqueta explícita
node:22.23.4-*, no un digest viejo ninode:20. - La imagen se reconstruyó y
node -vdentro coincide. - Tras el despliegue, el tráfico lo sirve la compilación nueva y no una en caché.
Si solo tienes diez minutos, haz los puntos 1, 3 y 5. Cubren las dos RCE críticas y el parche que mi propia fijación había congelado.



