O Header Que Pula a Verificação: Bypass do Middleware do Next.js
O desafio
O console interno da Mereton coloca seu muro de login no middleware do Next.js: toda requisição para /admin deveria passar primeiro por ele. Um pesquisador percebeu que o framework confia em um header que ele usa para falar consigo mesmo, e que nada impede você de enviar esse header de fora. A requisição para o dashboard de admin está carregada no editor. Faça o middleware sair do caminho e leia a chave de API de admin que o dashboard exibe assim que você entra.
O que você vai aprender
- Explicar por que um valor que o framework usa para confiar em si mesmo nunca deve ser aceito de um cliente
- Reproduzir o bypass do x-middleware-subrequest enviando o header com um valor repetido
- Ler uma resposta de redirect em busca da pista que nomeia o middleware que está sendo pulado
- Relacionar isso com a regra do X-Forwarded-For: confie no que o seu edge escreve, não no que chega
- Reconhecer que autenticação aplicada apenas no middleware é um ponto único que pode ser contornado
Habilidades testadas
Pré-requisitos
- A estrutura de uma requisição HTTP
- O que um middleware faz em um framework web
Como funciona
Um framework web muitas vezes faz requisições para os próprios componentes internos e as marca com um header para não entrar em loop infinito. O Next.js usava x-middleware-subrequest exatamente para isso. O problema era que esse mesmo header decidia se o middleware rodava: o framework contava quantas vezes o nome do middleware atual aparecia nele e, quando a contagem chegava ao limite de recursão de cinco, presumia um loop e pulava o middleware.
Nada removia esse header no edge, então um navegador também podia enviá-lo. Defina o valor como o caminho do módulo do próprio middleware, repetido cinco vezes, e a camada de autenticação simplesmente não rodava. A requisição chegava à página protegida como se tivesse sido aprovada.
A regra geral é que um token que significa esta requisição é interna não pode ser forjável de fora, o que na prática quer dizer que a fronteira precisa remover qualquer cópia recebida e escrever a sua própria. Um header, por si só, nunca é isso.
Erros comuns
- Enviar um único
middleware. Versões antigas do Next.js pulavam o middleware com uma cópia só, mas esta conta as cópias e só sai do caminho no limite de recursão de cinco. - Alterar o path ou o Host. O endpoint e o host estão corretos. Só o header de confiança é a porta de entrada.
- Ler o redirect de login como um beco sem saída. O comentário dele nomeia o módulo do middleware, que é o valor de que você precisa.
- Responder com o destino do redirect.
/login?next=/adminé o muro, não o prêmio.
Como se proteger
Trate o header como entrada hostil.
- Remova
x-middleware-subrequestna CDN ou no reverse proxy para que ele nunca chegue de um cliente. As versões corrigidas do framework fazem isso internamente: atualize. - Não faça a autenticação depender de uma única passagem pelo middleware. Reverifique a autorização no route handler ou na camada de dados, onde um middleware pulado não ajuda.
- Aplique a mesma disciplina a todo header de confiança (
X-Forwarded-For,X-Real-IP, headers internos de autenticação): o único valor em que você pode confiar é o que o seu proxy mais externo escreveu.
Solução completa
Estatísticas da comunidade
Hacks de hoje relacionados
Colaboradores creditados
Estes hackers relataram problemas, melhoraram o conteúdo e ajudaram a fortalecer esta página.