NetCatTest

Zero-Day & Exploits

Next.js: bypass de autorização além do middleware

Um roteiro técnico para comparar HTML, RSC e APIs, revisar as CVEs de middleware e prefetch e testar autorização por usuário, tenant e objeto.

Por Daniel Felipe 8 min leitura

Uma página que redireciona para o login não prova que os dados por trás dela estão protegidos. Em aplicações Next.js, HTML, navegação do cliente, respostas RSC e handlers podem alcançar o mesmo recurso por caminhos diferentes. O pentest precisa comparar essas representações, não apenas a URL que aparece na barra do navegador.

A CVE-2025-29927 tornou conhecida uma falha de autorização no middleware. Em 2026, novos avisos envolvendo proxy e rotas de prefetch reforçaram a necessidade de analisar o fluxo completo. Este artigo propõe um roteiro ofensivo de autorização para ambientes sob teste, com casos negativos, evidências e critérios de reteste.

Como uma proteção contra recursão virou decisão de autorização

O postmortem do mantenedor explica o papel de x-middleware-subrequest: impedir recursão quando o middleware provoca novas requests. O erro de confiança aparece quando informação com essa finalidade interna é aceita de uma origem externa e influencia a decisão de executar o middleware.

O código abaixo é uma reconstrução didática dessa classe de erro, não a implementação de Next.js nem um payload do CVE. Ela torna visível por que o número de passagens informado pelo cliente não pode representar o estado real da execução.

function executarControle(entrada, contextoInterno) {
  const passagens = contextoInterno?.passagens ?? 0;
  if (!Number.isInteger(passagens) || passagens < 0) {
    throw new Error('contexto invalido');
  }
  return { verificarAutorizacao: true, passagens };
}

const entrada = { passagens: 999, usuario: null };
const decisao = executarControle(entrada, { passagens: 0 });
if (!decisao.verificarAutorizacao || decisao.passagens !== 0) {
  throw new Error('fronteira violada');
}

O dado externo não controla o contador. Ainda assim, atingir um limite interno deve produzir um comportamento explicitamente seguro, não conceder acesso a recursos. Contexto interno autenticado e autorização da operação são controles complementares, com finalidades diferentes.

No teste diferencial, registre em qual camada a decisão muda: CDN, servidor Next.js, middleware, matcher, renderização ou consulta. Headers e caminhos de prefetch podem selecionar transportes distintos para o mesmo recurso. Dois status diferentes não bastam; compare o objeto sensível retornado e a identidade que o backend usou na consulta.

Uma decisão próxima dos dados deve vincular sujeito, tenant e operação. O middleware pode rejeitar cedo, mas uma consulta como “pedido por ID” continua perigosa se não inclui a política correspondente. Repetir a matriz em HTML, RSC e API é o que diferencia uma correção arquitetural de uma regra que reconhece apenas uma variante de request.

A lição técnica da CVE-2025-29927

O aviso oficial de março de 2025 descreve a possibilidade de contornar verificações de autorização implementadas no middleware. Ele recomenda, como alternativa temporária à atualização, impedir que requests externas com x-middleware-subrequest cheguem à aplicação.

O ponto de análise é a fronteira de confiança de um header interno. Informação usada pelo framework para controlar processamento não deve ser aceita do cliente como justificativa para deixar de executar uma decisão de segurança.

O aviso registra versões historicamente corrigidas e proteção automática desse caso para hospedagens na Vercel. Essas condições são específicas daquele CVE. Não extrapole a proteção de um provedor para instalações próprias, para todos os proxies ou para os avisos posteriores.

Por que os casos de 2026 ampliam a matriz de testes

A release de maio de 2026 reuniu falhas de bypass, DoS, SSRF, cache poisoning e XSS. Entre os bypasses, os avisos documentam caminhos de segment-prefetch, tratamento de locale e parâmetros de rotas dinâmicas. Cada um tem pré-condições e intervalos de versão próprios.

O aviso de segment-prefetch no App Router, CVE-2026-44575, descreve variantes de transporte que podem alcançar uma página sem corresponder ao matcher previsto. Seu acompanhamento de correção incompleta informa que a primeira correção não se aplicava a middleware.ts com Turbopack. Passar no caso original não significa cobrir a variante descoberta depois.

Use a versão corrigida suportada no momento da implantação. Uma versão suficiente para bloquear o header de 2025 pode continuar afetada por outro caminho de 2026. Documente a versão real do build em vez de simplesmente anotar que o projeto foi atualizado.

Modele autorização por sujeito, objeto e operação

Considere uma aplicação fictícia de pedidos. Há um usuário do tenant Azul, outro do tenant Verde e um administrador. O objetivo é demonstrar se uma operação permitida para um sujeito continua recusada para os demais, independentemente da forma como a request chega ao backend.

Defina a decisão esperada antes de testar. Uma sessão válida não autoriza automaticamente acesso a outro tenant. Um identificador difícil de adivinhar também não substitui a política. O servidor precisa decidir quem pode ler ou modificar aquele objeto.

SujeitoObjetoOperaçãoDecisão esperada
Sem sessãoPedido privado AzulLeituraRecusar sem retornar os dados
Usuário AzulPedido Azul permitidoLeituraPermitir
Usuário VerdePedido AzulLeituraRecusar
Usuário Azul comumPedido AzulOperação administrativaRecusar
Administrador autorizadoPedido AzulOperação administrativaPermitir conforme a política

A matriz serve de contrato para comparar HTML, dados de navegação e endpoints. Ela também revela quando uma proteção pertence somente à apresentação da página.

Compare as requests que o próprio cliente produz

No laboratório local, capture uma navegação legítima pelo painel de rede. Preserve método, rota, headers relevantes e tipo de resposta. Repita o caso removendo a sessão ou usando o usuário de outro tenant. Mude uma variável por vez e correlacione a resposta com os registros da decisão no servidor.

O exemplo abaixo faz apenas uma leitura de uma rota fictícia no loopback. Não contém uma reprodução automática dos CVEs:

curl --max-time 5 --path-as-is -sS -D resposta.headers \
  http://127.0.0.1:3000/api/pedidos/pedido-azul-lab \
  -o resposta.body

sha256sum resposta.body

Para a comparação autenticada, use credenciais sintéticas do laboratório por um arquivo local protegido. Não publique cookies ou bearer tokens no relatório. Grave hashes dos corpos e trechos mínimos que expliquem a diferença entre acesso permitido e recusado.

Quando houver Server Actions, use as requests reais dessa funcionalidade como base. Não invente um endpoint porque o nome parece plausível. O teste precisa exercitar uma operação existente, com seu formato e contexto próprios.

Normalize os caminhos sem perder a request original

Proxy, matcher e roteador podem interpretar uma mesma entrada de formas diferentes. Por isso, mantenha tanto o caminho original quanto a rota resolvida nos registros do laboratório. Variantes de locale, prefetch e parâmetros devem ser selecionadas conforme as funcionalidades realmente habilitadas.

Monte pares equivalentes de leitura e compare o objeto retornado. Uma resposta 200 de uma página pública de erro não é um bypass. Um redirect seguido automaticamente também pode esconder a primeira decisão. Registre a cadeia de respostas e analise o corpo antes de classificar o caso.

Desabilite o cache no reteste inicial ou identifique claramente suas entradas. Depois, teste o comportamento com cache, separando usuários e tenants. Um corpo de outro usuário pode representar uma falha de cache ou autorização; o diagnóstico exige seguir a origem dos dados.

A decisão deve existir junto do acesso aos dados

O guia de segurança de dados do Next.js recomenda uma camada de acesso a dados no servidor, com autorização e retornos mínimos. Middleware ou proxy podem rejeitar requests cedo, mas handlers e funções que expõem dados ainda precisam aplicar a política apropriada.

Na aplicação fictícia, a busca de um pedido deve incorporar o tenant autorizado e a operação, não apenas o ID recebido. Isso reduz a chance de um novo caminho de renderização reutilizar uma consulta desprotegida. A OWASP reforça negação por padrão e verificação de permissões a cada request.

Reteste o patch e a arquitetura

Depois da atualização, repita os casos associados aos avisos aplicáveis e toda a matriz de sujeitos. Confirme que leituras permitidas continuam funcionando e que recusas não incluem os dados protegidos. Para operações de escrita, verifique também o estado persistido, porque um erro de resposta pode ocorrer depois de uma mutação indevida.

O relatório deve identificar build, ambiente, router utilizado, intermediários, caso mínimo, objeto sintético e resultado. Diferencie bypass do middleware, autorização ausente no handler, vazamento de cache e hipótese sem comprovação.

A pergunta decisiva é simples: o servidor continua negando acesso ao mesmo objeto quando muda o caminho de transporte? Uma política consistente responde a essa pergunta em todas as representações do recurso.

Escrito por

Daniel Felipe é criador do NetCatTest e produz conteúdos sobre cibersegurança, privacidade digital, OSINT, laboratórios autorizados e ferramentas para estudo técnico responsável.

Compartilhar

Enviar este artigo