Recientemente, decidí colaborar en una investigación con Yasser Allam, conocido por el seudónimo inzo_. Después de discutir múltiples objetivos potenciales, decidimos centrar nuestra atención en Next.js (que tiene 130,000 estrellas en GitHub y más de 9.4 millones de descargas semanales). Es un marco con el que estoy muy familiarizado, con el que tengo una hermosa experiencia creativa, como lo demuestran mis investigaciones anteriores. Por lo tanto, el “nosotros” en este artículo se refiere naturalmente a los dos.
Next.js es un marco de JavaScript de función completa basado en React, que cuenta con una rica variedad de características, siendo el lugar ideal para profundizar en los detalles. Con fe, curiosidad y resiliencia, emprendemos un viaje para explorar esos rincones poco conocidos y encontrar los tesoros que se esconden en ellos.
Poco después, descubrimos un problema grave en el middleware. Su alcance es amplio, todas las versiones están afectadas y no se requieren condiciones previas para explotar esta vulnerabilidad; pronto realizaremos una demostración detallada.
Índice
Middleware de Next.js
Herramienta de autorización: código antiguo de nivel tesoro
Secuencia de ejecución y middlewareInfo.name
Herramienta de autorización: Ayer se convirtió en poesía, hoy es aún más valiosa
/src directorio
Máxima profundidad de recursión
Explotación de vulnerabilidades
Eludir autorización/reescribir
Evitar CSP
Realizar DoS a través de envenenamiento de caché (¿Qué?)
aclarar
Anuncio de seguridad - CVE-2025-29927
Descargo de responsabilidad
Conclusión
Middleware de Next.js
El middleware te permite ejecutar código antes de que se complete la solicitud. Luego, puedes modificar el contenido de la respuesta según la solicitud entrante, ya sea reescribiendo, redirigiendo, modificando las cabeceras de la solicitud o respuesta, o devolviendo directamente la respuesta (extraído de la documentación de Next.js).
Como un marco completo, Next.js tiene su propio middleware, que es una característica importante y ampliamente utilizada. Sus escenarios de aplicación son numerosos, siendo los más importantes los siguientes:
Reescritura de ruta (Path rewriting)
Redirecciones del lado del servidor
Agregar encabezados de información (como CSP, etc.) a la respuesta
Lo más importante es: autenticación (Authentication) y autorización (Authorization)
Un uso común de los middleware es la autorización, que implica proteger rutas específicas basándose en condiciones particulares.
Verificación de identidad y autorización: asegúrese de la identidad del usuario y verifique las cookies de sesión (documentación de Next.js) antes de otorgar acceso a páginas específicas o rutas de API.
Ejemplo: Cuando un usuario intenta acceder a /dashboard/admin, la solicitud primero pasará a través de un middleware, que verificará si la cookie de sesión del usuario es válida y si tiene los permisos necesarios. Si la validación es exitosa, el middleware reenviará la solicitud; de lo contrario, el middleware redirigirá al usuario a la página de inicio de sesión:
Herramienta de autorización: Código antiguo de nivel tesoro
Como dijo una gran persona una vez, “talk is cheap, show me the bug”, evitemos demasiada narración y vayamos directamente al grano; al revisar la versión anterior del marco (v12.0.7), encontramos este fragmento de código:
Cuando una aplicación de Next.js utiliza middleware, se llama a la función runMiddleware. Además de su función principal, esta función también obtiene el valor del encabezado x-middleware-subrequest y lo utiliza para determinar si se debe aplicar el middleware. Este valor del encabezado se divide en una lista utilizando dos puntos (:) como separador, y luego se verifica si esta lista contiene el valor de middlewareInfo.name. Esto significa que si añadimos un encabezado x-middleware-subrequest con el valor correcto en la solicitud, el middleware—sin importar su propósito—se ignorará por completo, la solicitud se reenviará a través de NextResponse.next() y completará el camino hacia el destino original, sin estar influenciada por ningún middleware. Este encabezado y su valor actúan como una “llave maestra”, que puede eludir todas las reglas. En este punto, hemos llegado a darnos cuenta de que hemos descubierto un problema sorprendente, y ahora necesitamos completar las últimas piezas del rompecabezas.
Para que nuestra “llave maestra” funcione, su valor debe incluir middlewareInfo.name, pero ¿cuál es exactamente ese valor?
Secuencia de ejecución y middlewareInfo.name
El valor de middlewareInfo.name es muy fácil de deducir, ya que es simplemente la ruta donde se encuentra el middleware. Para entender esto, necesitamos tener una breve idea de cómo se configuraba el middleware en las versiones anteriores.
Primero, antes de la versión 12.2—en la que se realizaron cambios en el acuerdo de middleware—los archivos debían nombrarse como _middleware.ts. Además, el enrutador de la aplicación (router) solo se introdujo en la versión 13 de Next.js. El único enrutador que existía en ese momento era el enrutador de páginas, por lo que el archivo debía colocarse dentro de la carpeta de páginas (específica del enrutador).
Con esta información, podemos deducir la ruta exacta del middleware y, por lo tanto, adivinar el valor del encabezado x-middleware-subrequest. Este valor está compuesto únicamente por el nombre del directorio (es decir, el nombre del enrutador único que existía en ese momento) y el nombre del archivo, siguiendo la convención de nomenclatura que comenzaba con un guion bajo en ese momento:
x-middleware-subrequest: pages/_middleware
Cuando intentamos eludir aquellos middleware configurados para redirigir los intentos de acceso desde /dashboard/team/admin a /dashboard:
¡Lo logramos, hemos infiltrado ⚔️
Ahora podemos eludir completamente el middleware, evitando así cualquier sistema de protección basado en él, siendo el más típico la autorización, como en nuestro ejemplo anterior. Este descubrimiento es bastante sorprendente, pero hay otros puntos a considerar.
Las versiones anteriores a 12.2 permitían colocar uno o varios archivos _middleware en cualquier ubicación del árbol de directorios (comenzando desde la carpeta pages), y tenían un orden de ejecución, como se puede ver en la captura de pantalla de la antigua documentación recuperada del Archivo Web:
¿Qué significa esto para nuestra explotación de vulnerabilidades?
Posibilidad = Número de niveles en el camino
Por lo tanto, para acceder a /dashboard/panel/admin (protegido por middleware), el valor de middlewareInfo.name puede tener tres posibilidades, y correspondientemente, el valor de x-middleware-subrequest también puede tener tres posibilidades:
pages/_middleware
o
pages/dashboard/_middleware
o
pages/dashboard/panel/_middleware
Herramienta de autorización: Ayer se convirtió en poesía, hoy es aún más valiosa
Hasta ahora, creemos que solo las versiones anteriores a la 13 son vulnerables, ya que el middleware se ha movido en el código fuente y aún no hemos cubierto todos sus aspectos. Suponemos que los mantenedores deben haber notado esta vulnerabilidad y la han corregido antes de los cambios significativos en la versión 13, por lo que informamos a los mantenedores del marco sobre esta vulnerabilidad y continuamos nuestra investigación.
Lo que nos sorprendió enormemente fue que, dos días después de su descubrimiento inicial, encontramos que todas las versiones de Next.js, desde la versión 11.1.4, tenían vulnerabilidades. El código ya no está en la misma ubicación y la lógica de explotación ha cambiado ligeramente.
Como se mencionó anteriormente, a partir de la versión 12.2, el archivo ya no contiene subrayados y debe nombrarse simplemente como middleware.ts. Además, ya no se encuentra en la carpeta de pages (lo cual es conveniente para nosotros, ya que a partir de la versión 13 se introdujo el enrutador de aplicaciones, lo que duplicaría las posibilidades).
Teniendo eso en cuenta, la carga útil para las primeras versiones comenzando con la versión 12.2 es muy simple:
Teniendo esto en cuenta, la primera versión de la carga útil a partir de la versión 12.2 es muy simple:
x-middleware-subrequest: middleware
/src directorio
También se debe considerar que Next.js ofrece la posibilidad de crear un directorio /src:
(Documentación de Next.js) Como una alternativa a tener el directorio especial de Next.js app o pages en la raíz del proyecto, Next.js también admite colocar el código de la aplicación en el directorio src como un patrón común. (Documentación de Next.js)
En este caso, el payload será:
x-middleware-subrequest: src/middleware
Por lo tanto, sin importar cuántos niveles haya en la ruta, solo hay dos posibilidades en total. Esto simplifica la dificultad de explotación de vulnerabilidades en las versiones relevantes.
En la última versión, ha habido un pequeño cambio (les aseguramos que es la última vez).
Máxima profundidad de recursión
En la versión actualizada, la lógica ha cambiado un poco, por favor mira este fragmento de código:
v15.1.7
Al igual que antes, el sistema buscará el valor del encabezado x-middleware-subrequest y formará una lista utilizando dos puntos como separador. Pero esta vez, las condiciones para el reenvío directo de la solicitud, es decir, ignorar las reglas de middleware, son diferentes:
El valor de la constante depth debe ser mayor o igual al valor de la constante MAX_RECURSION_DEPTH (es decir, 5). Durante el proceso de asignación, cada vez que un valor en la lista subrequests (es decir, los valores de encabezado separados por :) es igual a params.name (es decir, la ruta del middleware), la constante depth aumenta en 1. Como se mencionó anteriormente, aquí solo hay dos posibilidades: middleware o src/middleware.
Por lo tanto, para eludir el middleware, solo necesitamos agregar los siguientes encabezados/valores a la solicitud:
Este fragmento de código parece estar diseñado para evitar que las solicitudes recursivas queden atrapadas en un bucle infinito.
Explotación de vulnerabilidades
Dado que sabemos que le gusta este tipo de contenido, aquí hay algunos casos reales del Programa de Recompensas por Errores.
Eludir autorización/reescribir
En este ejemplo, cuando intentamos acceder a /admin/login, recibimos una respuesta 404. De los encabezados de respuesta se puede ver que el middleware realizó una reescritura de la ruta para evitar el acceso de usuarios no autorizados o inapropiados:
Pero utiliza nuestra herramienta autorizada:
Podemos acceder a este punto final sin obstáculos, el middleware se ignora por completo. Versión objetivo de Next.js: 15.1.7
Evitar CSP
Esta vez el sitio web utiliza middleware para configurar, además de otras funciones, CSP y cookies:
Pasemos por alto esto:
Target next.js version: 15.0.3Versión de next.js objetivo: 15.0.3
Nota: Presta atención a las diferencias en el payload de los dos objetivos, uno de los cuales utiliza el directorio src/ y el otro no.
Realizar DoS a través de envenenamiento de caché (¿Qué?)
Sí, a través de esta vulnerabilidad también se podría llevar a cabo un ataque DoS de envenenamiento de caché. Esto claramente no es lo que primero buscamos, pero si no hay rutas sensibles protegidas y no hay puntos de explotación más interesantes, entonces ciertas situaciones podrían llevar a un rechazo de servicio por envenenamiento de caché (CPDoS):
Supongamos que un sitio web reescribe las rutas de los usuarios según su ubicación geográfica, añadiendo (/en, /fr, etc.), y que no proporciona páginas o recursos en la ruta raíz (/). Si eludimos el middleware, evitaremos la reescritura y finalmente llegaremos a la página raíz. Dado que los desarrolladores no tenían la intención de permitir que los usuarios accedieran a la página raíz, no se proporcionó la página correspondiente, por lo que obtendremos un 404 (o, dependiendo de la configuración/tipo de reescritura, podría ser un 500).
Si el sitio web utiliza un sistema de caché/CDN, es posible que se vea obligado a almacenar en caché las respuestas 404, lo que puede hacer que la página no esté disponible y afectar gravemente la disponibilidad del sitio.
aclarar
Desde la publicación del anuncio de seguridad, hemos recibido consultas de algunas personas que están preocupadas por la seguridad de sus aplicaciones y no comprenden del todo el alcance del ataque. Es necesario aclarar que el elemento vulnerable es el middleware. Si no está utilizando middleware (o al menos no lo está utilizando para fines sensibles), no hay necesidad de preocuparse (sin embargo, verifique el aspecto de DoS mencionado anteriormente), ya que eludir el middleware no eludirá ningún mecanismo de seguridad real.
De lo contrario, las consecuencias pueden ser desastrosas, le recomendamos que implemente rápidamente las medidas de orientación en el aviso de seguridad.
Anuncio de seguridad - CVE-2025-29927
parche
Este problema se ha solucionado en Next.js 15.x en la versión 15.2.3.
Este problema se ha solucionado en la versión 14.2.25 de Next.js 14.x
Para las versiones de Next.js de 11.1.4 a 13.5.6, recomendamos consultar las siguientes soluciones.
solución
Si no puedes actualizar a una versión segura, te recomendamos que bloquees las solicitudes de usuarios externos que contengan el encabezado de solicitud x-middleware-subrequest de acceder a tu aplicación Next.js.
Al redactar este artículo, las aplicaciones desplegadas en Vercel y Netlify ya no parecen verse afectadas por esta vulnerabilidad (actualización: debido a la gran cantidad de falsos positivos, Cloudflare ha ajustado la regla para que solo tenga efecto cuando el usuario la active manualmente; estos falsos positivos no lograron distinguir efectivamente entre las solicitudes de usuarios legítimos y las de posibles atacantes).
Descargo de responsabilidad
Este estudio se publica únicamente con fines educativos, con el objetivo de ayudar a los desarrolladores a entender la raíz del problema, o inspirar a investigadores / cazadores de vulnerabilidades en su trabajo de investigación futuro. Este documento sirve como material complementario al aviso de seguridad, proporcionando una explicación y aclaración adicional sobre la naturaleza de la vulnerabilidad, ya que en el aviso se han hecho públicos los encabezados de solicitud que causaron dicha vulnerabilidad (así como las diferencias de envío relacionadas).
Declaramos explícitamente que no apoyamos el uso no ético de este documento.
Conclusión
Como se destaca en este artículo, esta vulnerabilidad ha existido en el código fuente de Next.js durante varios años, evolucionando con los middleware y sus versiones. Cualquier software puede tener vulnerabilidades graves, pero cuando afecta a uno de los frameworks más populares, se vuelve especialmente peligroso y puede tener serias consecuencias para un ecosistema más amplio. Como se mencionó anteriormente, al momento de redactar este artículo, Next.js tiene cerca de 10 millones de descargas semanales. Se utiliza ampliamente en campos críticos, desde servicios bancarios hasta blockchain. El riesgo aumenta aún más cuando las vulnerabilidades afectan a funciones maduras de las que dependen los usuarios, como la autorización y la autenticación.
El equipo de Vercel se tomó unos días para resolver esta vulnerabilidad, pero cabe destacar que, una vez que se dieron cuenta del problema, la solución fue enviada y fusionada en unas pocas horas en una nueva versión (incluyendo la portación hacia atrás).
Línea de tiempo :
27 de febrero de 2025: Se informó a los mantenedores sobre la vulnerabilidad (en ese momento creíamos que solo las versiones 12.0.0 a 12.0.7 estaban afectadas, y se señaló esto en el informe).
1 de marzo de 2025: Se envió el segundo correo electrónico, indicando que en realidad todas las versiones tienen vulnerabilidades, incluida la última versión estable.
5 de marzo de 2025: recibimos una respuesta preliminar del equipo de Vercel, indicando que la versión 12.x ya no se mantiene (posiblemente no han leído nuestro modelo de anuncio de seguridad adjunto en el segundo correo electrónico, sin darse cuenta de que todas las versiones están afectadas).
5 de marzo de 2025: volver a enviar el correo, por favor el equipo revise lo antes posible el segundo correo y la plantilla del aviso de seguridad.
11 de marzo de 2025: reenvía el correo electrónico para confirmar si la nueva información ha sido aceptada.
17 de marzo de 2025: se recibió la respuesta del equipo de Vercel, confirmando que se ha adoptado la información relevante.
18 de marzo de 2025: Recibí un correo electrónico del equipo de Vercel, indicando que el informe ha sido aceptado y que el parche de corrección se ha completado. Unas horas más tarde, se lanzó la versión 15.2.3 que incluye la corrección (y también incluye correcciones retroactivas).
21 de marzo de 2025: se publica el aviso de seguridad oficial.
En general, el proceso de búsqueda de vulnerabilidades de día cero solo es emocionante y emocionante en el momento en que se encuentra una pista; el resto del tiempo es como un viaje lleno de incertidumbres: para los curiosos, puede traer recompensas en conocimiento; para los impacientes, este viaje parece especialmente largo. No dudes, trabajar en equipo siempre es mucho más fácil que cruzar el desierto solo.
Esta página puede contener contenido de terceros, que se proporciona únicamente con fines informativos (sin garantías ni declaraciones) y no debe considerarse como un respaldo por parte de Gate a las opiniones expresadas ni como asesoramiento financiero o profesional. Consulte el Descargo de responsabilidad para obtener más detalles.
Next.js y vulnerabilidades de middleware: mecanismos de autorización fallidos
Artículo de: Rachid.A
Traducción: Yewlne
01 texto traducido
Recientemente, decidí colaborar en una investigación con Yasser Allam, conocido por el seudónimo inzo_. Después de discutir múltiples objetivos potenciales, decidimos centrar nuestra atención en Next.js (que tiene 130,000 estrellas en GitHub y más de 9.4 millones de descargas semanales). Es un marco con el que estoy muy familiarizado, con el que tengo una hermosa experiencia creativa, como lo demuestran mis investigaciones anteriores. Por lo tanto, el “nosotros” en este artículo se refiere naturalmente a los dos.
Next.js es un marco de JavaScript de función completa basado en React, que cuenta con una rica variedad de características, siendo el lugar ideal para profundizar en los detalles. Con fe, curiosidad y resiliencia, emprendemos un viaje para explorar esos rincones poco conocidos y encontrar los tesoros que se esconden en ellos.
Poco después, descubrimos un problema grave en el middleware. Su alcance es amplio, todas las versiones están afectadas y no se requieren condiciones previas para explotar esta vulnerabilidad; pronto realizaremos una demostración detallada.
Índice
Middleware de Next.js
Herramienta de autorización: código antiguo de nivel tesoro
Secuencia de ejecución y middlewareInfo.name
Herramienta de autorización: Ayer se convirtió en poesía, hoy es aún más valiosa
/src directorio
Máxima profundidad de recursión
Explotación de vulnerabilidades
Eludir autorización/reescribir
Evitar CSP
Realizar DoS a través de envenenamiento de caché (¿Qué?)
aclarar
Anuncio de seguridad - CVE-2025-29927
Descargo de responsabilidad
Conclusión
Middleware de Next.js
El middleware te permite ejecutar código antes de que se complete la solicitud. Luego, puedes modificar el contenido de la respuesta según la solicitud entrante, ya sea reescribiendo, redirigiendo, modificando las cabeceras de la solicitud o respuesta, o devolviendo directamente la respuesta (extraído de la documentación de Next.js).
Como un marco completo, Next.js tiene su propio middleware, que es una característica importante y ampliamente utilizada. Sus escenarios de aplicación son numerosos, siendo los más importantes los siguientes:
Reescritura de ruta (Path rewriting)
Redirecciones del lado del servidor
Agregar encabezados de información (como CSP, etc.) a la respuesta
Lo más importante es: autenticación (Authentication) y autorización (Authorization)
Un uso común de los middleware es la autorización, que implica proteger rutas específicas basándose en condiciones particulares.
Verificación de identidad y autorización: asegúrese de la identidad del usuario y verifique las cookies de sesión (documentación de Next.js) antes de otorgar acceso a páginas específicas o rutas de API.
Ejemplo: Cuando un usuario intenta acceder a /dashboard/admin, la solicitud primero pasará a través de un middleware, que verificará si la cookie de sesión del usuario es válida y si tiene los permisos necesarios. Si la validación es exitosa, el middleware reenviará la solicitud; de lo contrario, el middleware redirigirá al usuario a la página de inicio de sesión:
Herramienta de autorización: Código antiguo de nivel tesoro
Como dijo una gran persona una vez, “talk is cheap, show me the bug”, evitemos demasiada narración y vayamos directamente al grano; al revisar la versión anterior del marco (v12.0.7), encontramos este fragmento de código:
Cuando una aplicación de Next.js utiliza middleware, se llama a la función runMiddleware. Además de su función principal, esta función también obtiene el valor del encabezado x-middleware-subrequest y lo utiliza para determinar si se debe aplicar el middleware. Este valor del encabezado se divide en una lista utilizando dos puntos (:) como separador, y luego se verifica si esta lista contiene el valor de middlewareInfo.name. Esto significa que si añadimos un encabezado x-middleware-subrequest con el valor correcto en la solicitud, el middleware—sin importar su propósito—se ignorará por completo, la solicitud se reenviará a través de NextResponse.next() y completará el camino hacia el destino original, sin estar influenciada por ningún middleware. Este encabezado y su valor actúan como una “llave maestra”, que puede eludir todas las reglas. En este punto, hemos llegado a darnos cuenta de que hemos descubierto un problema sorprendente, y ahora necesitamos completar las últimas piezas del rompecabezas.
Para que nuestra “llave maestra” funcione, su valor debe incluir middlewareInfo.name, pero ¿cuál es exactamente ese valor?
Secuencia de ejecución y middlewareInfo.name
El valor de middlewareInfo.name es muy fácil de deducir, ya que es simplemente la ruta donde se encuentra el middleware. Para entender esto, necesitamos tener una breve idea de cómo se configuraba el middleware en las versiones anteriores.
Primero, antes de la versión 12.2—en la que se realizaron cambios en el acuerdo de middleware—los archivos debían nombrarse como _middleware.ts. Además, el enrutador de la aplicación (router) solo se introdujo en la versión 13 de Next.js. El único enrutador que existía en ese momento era el enrutador de páginas, por lo que el archivo debía colocarse dentro de la carpeta de páginas (específica del enrutador).
Con esta información, podemos deducir la ruta exacta del middleware y, por lo tanto, adivinar el valor del encabezado x-middleware-subrequest. Este valor está compuesto únicamente por el nombre del directorio (es decir, el nombre del enrutador único que existía en ese momento) y el nombre del archivo, siguiendo la convención de nomenclatura que comenzaba con un guion bajo en ese momento:
x-middleware-subrequest: pages/_middleware
Cuando intentamos eludir aquellos middleware configurados para redirigir los intentos de acceso desde /dashboard/team/admin a /dashboard:
¡Lo logramos, hemos infiltrado ⚔️
Ahora podemos eludir completamente el middleware, evitando así cualquier sistema de protección basado en él, siendo el más típico la autorización, como en nuestro ejemplo anterior. Este descubrimiento es bastante sorprendente, pero hay otros puntos a considerar.
Las versiones anteriores a 12.2 permitían colocar uno o varios archivos _middleware en cualquier ubicación del árbol de directorios (comenzando desde la carpeta pages), y tenían un orden de ejecución, como se puede ver en la captura de pantalla de la antigua documentación recuperada del Archivo Web:
¿Qué significa esto para nuestra explotación de vulnerabilidades?
Posibilidad = Número de niveles en el camino
Por lo tanto, para acceder a /dashboard/panel/admin (protegido por middleware), el valor de middlewareInfo.name puede tener tres posibilidades, y correspondientemente, el valor de x-middleware-subrequest también puede tener tres posibilidades:
pages/_middleware
o
pages/dashboard/_middleware
o
pages/dashboard/panel/_middleware
Herramienta de autorización: Ayer se convirtió en poesía, hoy es aún más valiosa
Hasta ahora, creemos que solo las versiones anteriores a la 13 son vulnerables, ya que el middleware se ha movido en el código fuente y aún no hemos cubierto todos sus aspectos. Suponemos que los mantenedores deben haber notado esta vulnerabilidad y la han corregido antes de los cambios significativos en la versión 13, por lo que informamos a los mantenedores del marco sobre esta vulnerabilidad y continuamos nuestra investigación.
Lo que nos sorprendió enormemente fue que, dos días después de su descubrimiento inicial, encontramos que todas las versiones de Next.js, desde la versión 11.1.4, tenían vulnerabilidades. El código ya no está en la misma ubicación y la lógica de explotación ha cambiado ligeramente.
Como se mencionó anteriormente, a partir de la versión 12.2, el archivo ya no contiene subrayados y debe nombrarse simplemente como middleware.ts. Además, ya no se encuentra en la carpeta de pages (lo cual es conveniente para nosotros, ya que a partir de la versión 13 se introdujo el enrutador de aplicaciones, lo que duplicaría las posibilidades).
Teniendo eso en cuenta, la carga útil para las primeras versiones comenzando con la versión 12.2 es muy simple:
Teniendo esto en cuenta, la primera versión de la carga útil a partir de la versión 12.2 es muy simple:
x-middleware-subrequest: middleware
/src directorio
También se debe considerar que Next.js ofrece la posibilidad de crear un directorio /src:
(Documentación de Next.js) Como una alternativa a tener el directorio especial de Next.js app o pages en la raíz del proyecto, Next.js también admite colocar el código de la aplicación en el directorio src como un patrón común. (Documentación de Next.js)
En este caso, el payload será:
x-middleware-subrequest: src/middleware
Por lo tanto, sin importar cuántos niveles haya en la ruta, solo hay dos posibilidades en total. Esto simplifica la dificultad de explotación de vulnerabilidades en las versiones relevantes.
En la última versión, ha habido un pequeño cambio (les aseguramos que es la última vez).
Máxima profundidad de recursión
En la versión actualizada, la lógica ha cambiado un poco, por favor mira este fragmento de código:
v15.1.7
Al igual que antes, el sistema buscará el valor del encabezado x-middleware-subrequest y formará una lista utilizando dos puntos como separador. Pero esta vez, las condiciones para el reenvío directo de la solicitud, es decir, ignorar las reglas de middleware, son diferentes:
El valor de la constante depth debe ser mayor o igual al valor de la constante MAX_RECURSION_DEPTH (es decir, 5). Durante el proceso de asignación, cada vez que un valor en la lista subrequests (es decir, los valores de encabezado separados por :) es igual a params.name (es decir, la ruta del middleware), la constante depth aumenta en 1. Como se mencionó anteriormente, aquí solo hay dos posibilidades: middleware o src/middleware.
Por lo tanto, para eludir el middleware, solo necesitamos agregar los siguientes encabezados/valores a la solicitud:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
o
x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
¿Para qué se utilizó originalmente este código?
Este fragmento de código parece estar diseñado para evitar que las solicitudes recursivas queden atrapadas en un bucle infinito.
Explotación de vulnerabilidades
Dado que sabemos que le gusta este tipo de contenido, aquí hay algunos casos reales del Programa de Recompensas por Errores.
Eludir autorización/reescribir
En este ejemplo, cuando intentamos acceder a /admin/login, recibimos una respuesta 404. De los encabezados de respuesta se puede ver que el middleware realizó una reescritura de la ruta para evitar el acceso de usuarios no autorizados o inapropiados:
Pero utiliza nuestra herramienta autorizada:
Podemos acceder a este punto final sin obstáculos, el middleware se ignora por completo. Versión objetivo de Next.js: 15.1.7
Evitar CSP
Esta vez el sitio web utiliza middleware para configurar, además de otras funciones, CSP y cookies:
Pasemos por alto esto:
Target next.js version: 15.0.3Versión de next.js objetivo: 15.0.3
Nota: Presta atención a las diferencias en el payload de los dos objetivos, uno de los cuales utiliza el directorio src/ y el otro no.
Realizar DoS a través de envenenamiento de caché (¿Qué?)
Sí, a través de esta vulnerabilidad también se podría llevar a cabo un ataque DoS de envenenamiento de caché. Esto claramente no es lo que primero buscamos, pero si no hay rutas sensibles protegidas y no hay puntos de explotación más interesantes, entonces ciertas situaciones podrían llevar a un rechazo de servicio por envenenamiento de caché (CPDoS):
Supongamos que un sitio web reescribe las rutas de los usuarios según su ubicación geográfica, añadiendo (/en, /fr, etc.), y que no proporciona páginas o recursos en la ruta raíz (/). Si eludimos el middleware, evitaremos la reescritura y finalmente llegaremos a la página raíz. Dado que los desarrolladores no tenían la intención de permitir que los usuarios accedieran a la página raíz, no se proporcionó la página correspondiente, por lo que obtendremos un 404 (o, dependiendo de la configuración/tipo de reescritura, podría ser un 500).
Si el sitio web utiliza un sistema de caché/CDN, es posible que se vea obligado a almacenar en caché las respuestas 404, lo que puede hacer que la página no esté disponible y afectar gravemente la disponibilidad del sitio.
aclarar
Desde la publicación del anuncio de seguridad, hemos recibido consultas de algunas personas que están preocupadas por la seguridad de sus aplicaciones y no comprenden del todo el alcance del ataque. Es necesario aclarar que el elemento vulnerable es el middleware. Si no está utilizando middleware (o al menos no lo está utilizando para fines sensibles), no hay necesidad de preocuparse (sin embargo, verifique el aspecto de DoS mencionado anteriormente), ya que eludir el middleware no eludirá ningún mecanismo de seguridad real.
De lo contrario, las consecuencias pueden ser desastrosas, le recomendamos que implemente rápidamente las medidas de orientación en el aviso de seguridad.
Anuncio de seguridad - CVE-2025-29927
parche
Este problema se ha solucionado en Next.js 15.x en la versión 15.2.3.
Este problema se ha solucionado en la versión 14.2.25 de Next.js 14.x
Para las versiones de Next.js de 11.1.4 a 13.5.6, recomendamos consultar las siguientes soluciones.
solución
Si no puedes actualizar a una versión segura, te recomendamos que bloquees las solicitudes de usuarios externos que contengan el encabezado de solicitud x-middleware-subrequest de acceder a tu aplicación Next.js.
Severidad
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N (Severidad: 9.1/10, crítico)
Más información
Al redactar este artículo, las aplicaciones desplegadas en Vercel y Netlify ya no parecen verse afectadas por esta vulnerabilidad (actualización: debido a la gran cantidad de falsos positivos, Cloudflare ha ajustado la regla para que solo tenga efecto cuando el usuario la active manualmente; estos falsos positivos no lograron distinguir efectivamente entre las solicitudes de usuarios legítimos y las de posibles atacantes).
Descargo de responsabilidad
Este estudio se publica únicamente con fines educativos, con el objetivo de ayudar a los desarrolladores a entender la raíz del problema, o inspirar a investigadores / cazadores de vulnerabilidades en su trabajo de investigación futuro. Este documento sirve como material complementario al aviso de seguridad, proporcionando una explicación y aclaración adicional sobre la naturaleza de la vulnerabilidad, ya que en el aviso se han hecho públicos los encabezados de solicitud que causaron dicha vulnerabilidad (así como las diferencias de envío relacionadas).
Declaramos explícitamente que no apoyamos el uso no ético de este documento.
Conclusión
Como se destaca en este artículo, esta vulnerabilidad ha existido en el código fuente de Next.js durante varios años, evolucionando con los middleware y sus versiones. Cualquier software puede tener vulnerabilidades graves, pero cuando afecta a uno de los frameworks más populares, se vuelve especialmente peligroso y puede tener serias consecuencias para un ecosistema más amplio. Como se mencionó anteriormente, al momento de redactar este artículo, Next.js tiene cerca de 10 millones de descargas semanales. Se utiliza ampliamente en campos críticos, desde servicios bancarios hasta blockchain. El riesgo aumenta aún más cuando las vulnerabilidades afectan a funciones maduras de las que dependen los usuarios, como la autorización y la autenticación.
El equipo de Vercel se tomó unos días para resolver esta vulnerabilidad, pero cabe destacar que, una vez que se dieron cuenta del problema, la solución fue enviada y fusionada en unas pocas horas en una nueva versión (incluyendo la portación hacia atrás).
Línea de tiempo :
27 de febrero de 2025: Se informó a los mantenedores sobre la vulnerabilidad (en ese momento creíamos que solo las versiones 12.0.0 a 12.0.7 estaban afectadas, y se señaló esto en el informe).
1 de marzo de 2025: Se envió el segundo correo electrónico, indicando que en realidad todas las versiones tienen vulnerabilidades, incluida la última versión estable.
5 de marzo de 2025: recibimos una respuesta preliminar del equipo de Vercel, indicando que la versión 12.x ya no se mantiene (posiblemente no han leído nuestro modelo de anuncio de seguridad adjunto en el segundo correo electrónico, sin darse cuenta de que todas las versiones están afectadas).
5 de marzo de 2025: volver a enviar el correo, por favor el equipo revise lo antes posible el segundo correo y la plantilla del aviso de seguridad.
11 de marzo de 2025: reenvía el correo electrónico para confirmar si la nueva información ha sido aceptada.
17 de marzo de 2025: se recibió la respuesta del equipo de Vercel, confirmando que se ha adoptado la información relevante.
18 de marzo de 2025: Recibí un correo electrónico del equipo de Vercel, indicando que el informe ha sido aceptado y que el parche de corrección se ha completado. Unas horas más tarde, se lanzó la versión 15.2.3 que incluye la corrección (y también incluye correcciones retroactivas).
21 de marzo de 2025: se publica el aviso de seguridad oficial.
En general, el proceso de búsqueda de vulnerabilidades de día cero solo es emocionante y emocionante en el momento en que se encuentra una pista; el resto del tiempo es como un viaje lleno de incertidumbres: para los curiosos, puede traer recompensas en conocimiento; para los impacientes, este viaje parece especialmente largo. No dudes, trabajar en equipo siempre es mucho más fácil que cruzar el desierto solo.