
Demonstração educacional de uma vulnerabilidade de Server-Side Request Forgery (SSRF) no Next.js (CVE-2024-34351), com exemplos passo a passo de exploração e mitigação.
Este repositório pode servir de suporte para apresentar um ou mais meetup(s). O percurso é o seguinte…
Este trabalho é baseado principalmente em duas fontes:
1-csr-load-data vanilla react SPA loading data[!IMPORTANT] CSR (Client-Side Rendering): o código React é entregue ao navegador, que gera conteúdo que é inserido no DOM.

cd 1-csr-load-data
npm start

2-csr-router vanilla react SPA routing[!IMPORTANT] Após a página ser carregada pela primeira vez, navegar para outras páginas no mesmo site usa JavaScript para re-renderizar partes da página sem exigir uma atualização completa da página.
cd 2-csr-router
npm start

3-rsc-load-data React Server Components (Next.js impl) loading data[!IMPORTANT] Componentes React que são escritos para executar apenas no servidor, e não no navegador.

cd 3-rsc-load-data
npm run build
npm run start

4-rsc-router React Server Components (Next.js impl) routing[!IMPORTANT] Os componentes são executados apenas no servidor. O comportamento padrão é a renderização estática: os componentes são executados no momento da construção.
cd 4-rsc-router
npm run build
npm run start

5-SSR SSR Server Side Rendering[!IMPORTANT] SSR significa pré-renderizar componentes do cliente no servidor. O código React é executado no momento em que é solicitado. O resultado pode ser armazenado em cache para requisições futuras.
Melhor prática: definir componentes 'use client'; o mais abaixo possível na árvore de componentes.
[!IMPORTANT] "Em React, “hydration” é como React “anexa” ao HTML existente que já foi renderizado pelo React em um ambiente de servidor. Durante a hidratação, o React tentará anexar ouvintes de eventos à marcação existente e assumir a renderização do aplicativo no cliente. Em aplicativos totalmente construídos com React, você geralmente hidratará apenas uma “raiz”, uma vez na inicialização para todo o aplicativo."
cd 5-ssr
npm run build
npm run start

6-pages-router-ssg (Next.js impl)[!IMPORTANT] SSG (Static Site Generation) usando o pages router: o código React é executado quando você constrói seu aplicativo, e a saída gerada é estática.
cd 6-pages-router-ssg
npm run build
npm run start
7-pages-router-isr (Next.js impl)[!IMPORTANT] ISR (usando pages router): "O Next.js permite que você crie ou atualize páginas estáticas depois de construir seu site. A Regeneração Estática Incremental (ISR) permite que você use geração estática por página, sem precisar reconstruir o site inteiro. Com ISR, você pode manter os benefícios do estático enquanto escala para milhões de páginas."
cd 7-pages-router-isr
npm run build
npm run start
"os dados podem se tornar obsoletos no momento da requisição"
...
8-ssrf-14.1.014.1.1redirect(/blog/${inputValue});Next.JS executa a requisição no lado do servidor e depois retorna o resultado ao navegador:
redirect('/blog/123'); constrói a URL http://207.154.209.99/blog/123.
Para construir essa URL, Next.JS recupera, entre outros, o host 207.154.209.99 a partir do header HTTP da requisição inicial.Content-Type: text/x-component, então Next.JS requisita a URL com um HTTP GET.Para resultar em um SSRF no servidor alvo, é necessário executar outro servidor:
Content-Type: text/x-component, para toda requisição HEAD
8-ssrf-14.1.0Em /etc/nginx/sites-available/nextjs
Antes:
server {
listen 80 default_server;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Depois:
server {
listen 80;
server_name 207.154.209.99;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host 207.154.209.99;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Risco de efeito colateral...

As páginas no diretório app são Server Components por padrão. Isso é diferente do diretório pages, onde as páginas são Client Components.
Atualizar para Next.js 13 não requer o uso do novo App Router. Você pode continuar usando pages com novos recursos que funcionam em ambos os diretórios
Se você quiser comparar o desempenho de carregamento para as diferentes soluções, pode adicionar as métricas web core vitals em console.log.
ISR usando App router?
No Next.js App Router, todos os dados buscados são estáticos por padrão, renderizados no momento da construção. No entanto, isso pode ser facilmente alterado: o Next.js estende o objeto de opções do fetch para fornecer flexibilidade nas regras de cache e revalidação. Você pode usar a opção {next: {revalidate: number}} para atualizar dados estáticos em intervalos definidos ou quando ocorrerem alterações no backend (Regeneração Estática Incremental), enquanto a opção {cache: 'no-store'} pode ser passada na requisição fetch para dados dinâmicos (renderização no lado do servidor).