El AVIF que te ahorró kilobytes ahora puede ejecutar código: el RCE crítico de Next.js y dónde decodificar imágenes
El 25 de agosto de 2026 Vercel publicó 15.5.24 y 16.3.3 para corregir GHSA-2xp9-vwfh-vxw4: una ejecución remota de código no autenticada (CVSS 9.5) cuando el Image Optimization API de Next.js procesa archivos AVIF, causada por un heap buffer overflow en libheif. Qué significa para la arquitectura de tu pipeline de imágenes y por qué dónde decodificas es ahora una decisión de seguridad, no solo de rendimiento.
El AVIF que te ahorró kilobytes ahora puede ejecutar código: el RCE crítico de Next.js y dónde decodificar imágenes
El 25 de agosto de 2026, Vercel publicó Next.js 15.5.24 y 16.3.3 para corregir GHSA-2xp9-vwfh-vxw4: una vulnerabilidad crítica (CVSS 9.5) que permite ejecución remota de código sin autenticación cuando el Image Optimization API procesa archivos AVIF. La causa es un heap buffer overflow en libheif — la librería C que usa sharp — y los parches desactivan por completo la optimización de AVIF en servidor hasta que libheif publique su corrección. Para equipos web, la lección no es abandonar AVIF: es que decidir dónde se decodifican las imágenes pasó de ser una decisión de rendimiento a una decisión de seguridad.
Qué pasó exactamente
La cadena de fallo tiene tres eslabones: Next.js usa sharp para optimizar imágenes bajo demanda, sharp usa libheif para parsear archivos AVIF, y libheif tenía un heap buffer overflow en su código de escalado. Un AVIF manipulado con referencias anidadas de identity-derivation y auxiliary items fuerza a libheif a construir la imagen decodificada con dos entradas de canal Alpha a distinta profundidad de bits: el escalador reserva un buffer para la entrada de 8 bits pero escribe valores de 16 bits de la segunda entrada, desbordando aproximadamente 16.384 bytes fuera de la asignación.
Los investigadores (rootxharsh como finder, KarimPwnz como coordinator, atribuidos al equipo Hacktron) publicaron un proof-of-concept completo en Python junto con el advisory de libheif (GHSA-g89c-p67h-r497) y reportaron: "pudimos obtener RCE en múltiples aplicaciones". El alcance es amplio: afecta a todas las versiones de libheif hasta la 1.23.1, lo que se traduce en Next.js 10.0.0 hasta 15.5.23 y todas las 16.x hasta 16.3.2. La corrección no es inmediata del todo: las versiones parcheadas de Next.js desactivan la optimización de AVIF por completo, y hasta el 27 de agosto libheif aún no había publicado la v1.23.2 que permitiría reactivarla.
Hay un matiz que reduce el pánico: la optimización de AVIF en servidor solo está activa si tu next.config.js incluye explícitamente formats: ['image/avif']. Sin esa configuración, Next.js no pasa tus imágenes por el decodificador vulnerable. Y si tu aplicación está alojada en Vercel, la infraestructura de la plataforma absorbe la mitigación: Vercel declaró que las apps alojadas en su red no requieren actualización. El mismo release también parcheó un segundo crítico, CVE-2026-75604 (CVSS 9.0), un path traversal en servidores Windows — pero ese no toca nuestro dominio: el de las imágenes sí.
Por qué esto importa más allá de Next.js
Porque el mismo trio sharp + libheif + AVIF no vive solo en Next.js. Está en funciones serverless de procesamiento de imágenes, en microservicios de resize, en generadores de Open Graph, en pipelines de medios sintéticos que redimensionan salidas de modelos de IA. Cualquier lugar donde un servidor decodifique un AVIF que no controlas es, desde el 25 de agosto, una superficie potencial de ejecución de código.
Y aquí está la ironía que nos toca directamente: nosotros llevamos meses recomendando AVIF. En nuestro artículo sobre la migración de tres sitios a AVIF documentamos ahorros de 40% a 60% en peso de imagen y mejoras de LCP de 300 a 800 ms. AVIF sigue siendo el formato correcto para 2026 — 30-50% mejor compresión que JPEG (según el mismo análisis de caniuse y Morphix Tools que citamos ahí). Lo que cambió es el riesgo asociado a una arquitectura específica: decodificar archivos no confiables en un proceso servidor persistentemente expuesto.
Nadie debería concluir "AVIF era la trampa". La conclusión correcta es más incómoda: el formato que elegiste por rendimiento ahora determina tu superficie de ataque, y la superficie depende de dónde decodificas, no de qué formato usas.
Dónde decodificar: la matriz que usamos en Mintec
En los proyectos que migramos a Astro + Cloudflare la decisión fue estructural: las imágenes se comprimen en build-time y se sirven como archivos estáticos desde el edge. No existe un proceso servidor que reciba URLs arbitrarias y decida decodificar lo que llegue. Eso quedó evidente cuando llegó este advisory: nuestro pipeline no tenía el camino de ataque, porque el decodificador no es alcanzable por input no confiable.
| Arquitectura | Rendimiento | Superficie de ataque | Riesgo con AVIF hoy |
|---|---|---|---|
Build-time + CDN estático (Astro SSG, Next.js output: export) | Óptimo: cero trabajo en runtime, cache edge global | Mínima: el decodificador no acepta input del usuario | Bajo — la imagen que sirves fue validada en build |
| Edge/Workers con resize por query (Cloudflare Image Resizing, Vercel Edge) | Muy bueno: cache en borde, sin origen | Media: decodifica input del usuario, pero en sandbox efímero | Medio — la sandbox limita el daño, pero el overflow existe |
Optimización on-demand en servidor (Next.js next/image tradicional, sharp en Node) | Bueno, con coste de CPU por imagen nueva | Alta: proceso persistente, input 100% controlado por el atacante (URLs y headers) | Crítico — exactamente el caso de GHSA-2xp9-vwfh-vxw4 |
Decodificación en cliente (<picture> con AVIF nativo) | Depende del dispositivo del usuario | Ninguna servidor; el riesgo se mueve al navegador | Bajo — es el modelo de los navegadores desde 2020 |
La regla que aplicamos de ahora en adelante: el decodificador de imágenes debe vivir donde no pueda ser alcanzado por input no confiable — build-time, edge con sandbox, o el navegador del usuario. Un servidor Node con sharp escuchando requests de imagen no es "optimización", es una puerta con el código del atacante del otro lado.
Qué hacer hoy (checklist verificable)
- Audita tu configuración.
grep -r "formats" next.config.*en cada proyecto Next.js. Si apareceimage/avif, tienes el camino de ataque activo y necesitas el parche — no solo un WAF ni una promesa de "no recibimos archivos raros". Los atacantes no necesitan subir archivos: solo una URL que apunte a un AVIF remoto que ellos controlen. - Actualiza ya.
npm install [email protected](o15.5.24en la línea LTS) y corre el runbook de 24 horas que documentamos para releases programados: staging primero, smoke test de image optimization, verificación de lockfile. El advisory es del 25 de agosto; el PoC es público; la ventana de parcheo ya está abierta. - No reactives AVIF en
next/imagehasta que libheif publique su fix. Las versiones parcheadas lo desactivan por diseño. Si quieres AVIF servido en servidor, sirve archivos pre-comprimidos como estáticos (build-time) — exactamente el patrón de nuestros tres proyectos de migración — o usa un servicio de resize en edge. - Busca sharp/libheif fuera de Next.js. Serverless functions de resize, generadores de OG images, pipelines de video que extraen frames: cualquier proceso que decodifique AVIF no confiable con sharp < la versión que incluya libheif 1.23.2 tiene el mismo problema.
npm ls sharpy revisa la versión de libheif empaquetada. - Agrega capas de defensa. El principio que ya aplicamos con Trusted Types y CSP vale para imágenes: no existe un solo parche que te haga invulnerable, existe una arquitectura que limita lo que un input malicioso puede tocar. Restringe
remotePatternsde next/image a dominios que controlas, nunca dejes el optimizador abierto a URLs arbitrarias.
La decisión arquitectónica que este advisory confirma
Llevamos meses argumentando a favor de arquitecturas de contenido estático: el análisis comparativo Astro vs Next.js ya mostraba que la mayoría de sitios de contenido no necesita un runtime de servidor, y nuestra experiencia de seis meses con Astro + Cloudflare confirmó que el rendimiento no se sacrifica — se gana. Lo que no habíamos dimensionado del todo es que la superficie de parcheo también es arquitectura: cada runtime que agregas es un decodificador, un parser o un router que alguien va a tratar de romper.
Esta semana no se trata de AVIF. Se trata de que la optimización de imágenes en servidor — la práctica que adoptamos hace una década para "mejorar performance" — ahora se parece más a ejecutar código de terceros en tu máquina que a comprimir archivos. El consejo de seguridad más honesto que podemos dar: si tu sitio es contenido, no tengas un servidor que decodifique imágenes; y si lo necesitas, trátalo como lo que es: un servicio con input no confiable, con parcheo inmediato y monitoreo activo.
El AVIF que te ahorró kilobytes sigue siendo la decisión correcta. Lo que ya no es negociable es decidir dónde lo decodificas.
Preguntas Frecuentes
¿Qué corrige la vulnerabilidad crítica de Next.js con AVIF (GHSA-2xp9-vwfh-vxw4)?
Un heap buffer overflow en libheif, la librería C que usa sharp y que Next.js usa para optimizar imágenes. Un AVIF manipulado puede escribir ~16 KB fuera del buffer al escalar la imagen y lograr ejecución remota de código sin autenticación (CVSS 9.5). Se parchea en Next.js 15.5.24 y 16.3.3, publicadas el 25 de agosto de 2026.
¿Mi sitio Next.js está expuesto al RCE de AVIF?
Solo si usas next/image con optimización servidor y agregaste explícitamente image/avif a la configuración formats en next.config.js. Sin esa configuración, AVIF no se optimiza en servidor y la ruta no está expuesta. Los sitios alojados en Vercel están protegidos.
¿Debo dejar de usar AVIF?
No. El formato sigue siendo la mejor opción de compresión (30-50% menos peso que JPEG). Lo que cambia es dónde decodificas: evita decodificar en servidor archivos no confiables con sharp/libheif hasta que libheif publique la corrección (v1.23.2) y sirve AVIF pre-comprimido como archivos estáticos o desde un CDN.



