
Bypass de autenticación en middleware de Next.js
Al falsificar la cabecera de solicitud x-middleware-subrequest, se elude el mecanismo de autenticación del middleware de Next.js, permitiendo el acceso no autorizado a rutas protegidas.
El código fuente del proyecto proviene de P神, y la versión de Next.js es 15.2.2 (para Next.js 15.x, este problema se corrige en 15.2.3).
Asegúrate de tener Node y npm instalados. Verifica las versiones con los siguientes comandos:
node -v
npm -v
Instala las dependencias e inicia el proyecto
# 1. Entra en el directorio del proyecto
cd vulenv
# 2. Instala Yarn globalmente (si aún no está instalado)
npm install -g yarn
# 3. Instala las dependencias del proyecto
yarn install
# 4. Inicia el servidor de desarrollo
npm run dev
O todo de una vez:
cd vulenv && npm install -g yarn && yarn install && npm run dev
El resultado exitoso se muestra a continuación:


Configura VScode para depurar de la siguiente manera
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev",
"serverReadyAction": {
"pattern": "- Local:.+(https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
const run = withTaggedErrors(async function runWithTaggedErrors(params) {
var _params_request_body;
const runtime = await getRuntimeContext(params);
const subreq = params.request.headers[`x-middleware-subrequest`];
const subrequests = typeof subreq === 'string' ? subreq.split(':') : [];
const MAX_RECURSION_DEPTH = 5;
const depth = subrequests.reduce((acc, curr)=>curr === params.name ? acc + 1 : acc, 0);
if (depth >= MAX_RECURSION_DEPTH) {
return {
waitUntil: Promise.resolve(),
response: new runtime.context.Response(null, {
headers: {
'x-middleware-next': '1'
}
})
};
}
......
Una función de middleware cuyo propósito es detectar la profundidad de las llamadas recursivas y evitar bucles infinitos. Su mecanismo se basa en la cabecera de solicitud x-middleware-subrequest, que se divide por dos puntos (:) en varios nombres de subsolicitudes y cuenta cuántas veces coincide con el nombre del middleware actual params.name (es decir, el nivel de recursión). Cuando el nivel de recursión alcanza o supera el umbral establecido (por defecto MAX_RECURSION_DEPTH = 5), el middleware omite la lógica principal, como la verificación de identidad, y continúa con el flujo de procesamiento de la solicitud.
Consejo: para evitar la llamada recursiva infinita, la idea general es la siguiente
El usuario visita /dashboard
↓
El middleware intercepta y solicita /api/auth
↓
/api/auth vuelve a activar el middleware
↓
El middleware vuelve a solicitar /api/auth
↓
...
¡Bucle infinito! 🌀
El middleware se llama middleware; se puede construir la siguiente cabecera de solicitud:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
La construcción anterior hace que depth = 5, lo que activa directamente:
if (depth >= MAX_RECURSION_DEPTH)
Si la aplicación implementa la lógica de verificación de identidad en el middleware, esto hace que el middleware salga de la lógica de autenticación y devuelva
x-middleware-next: 1
Haciendo que la solicitud continúe hacia el backend y obtenga recursos protegidos sin autenticación.
Coloca un punto de interrupción en la posición que se muestra en la siguiente imagen (ruta detallada: CVE-2025-29927/vulenv/node_modules/next/dist/server/web/sandbox/sandbox.js) y luego inicia la depuración.

Envía el Payload

El punto de interrupción se detiene en la posición mostrada en la siguiente imagen, donde se puede ver que el valor de depth es 5

Continúa la ejecución y se podrán obtener los recursos protegidos

Escrito con base en Pocsuite3; consulta los detalles en Poc_CVE-2025-29927.py.

Next.js and the corrupt middleware: the authorizing artifact