Vulnerabilidade no middleware do Next.js
Vulnerabilidade crítica no Next.js permite burlar segurança. Atualize para a versão corrigida e proteja suas rotas.

Resumo: Uma vulnerabilidade crítica de autenticação no Next.js (CVE-2025-29927) permite que invasores ignorem verificações de middleware ao falsificar o cabeçalho x-middleware-subrequest
. Afeta versões de 11.1.4 até início da 15.x. Hospedagens gerenciadas, como Vercel, estão seguras, mas apps autohospedados que dependem de middleware para controle de acesso estão em risco. Atualize para uma versão corrigida (13.5.6, 14.2.24, 15.2.2+) ou adicione verificações de autenticação diretamente nas rotas protegidas se não puder atualizar ainda.
O Next.js esteve recentemente no centro de uma grande controvérsia de desenvolvimento web devido a uma vulnerabilidade crítica que permite que usuários não autenticados ignorem seus mecanismos de autorização. Esta vulnerabilidade foi atribuída à referência CVE-2025-29927 e possui uma pontuação CVSS 3.1 de 9.1.
A vulnerabilidade afeta todas as versões do Next.js da 11.1.4 até (mas não incluindo) as versões corrigidas: 13.5.6, 14.2.24 e 15.2.2.
O que é esta vulnerabilidade?
Descoberta por dois pesquisadores de segurança, zhero e inzo, ao analisar o código-fonte do Next.js, essa vulnerabilidade permite que invasores ignorem verificações de segurança manipulando um cabeçalho HTTP interno chamado x-middleware-subrequest
. O middleware geralmente é onde são realizadas essas verificações para garantir que os usuários possam acessar certas páginas e redirecioná-los com base em seu papel.
Por exemplo, ao criar um aplicativo SaaS, você normalmente verificaria no middleware se um usuário é um cliente pagante antes de permitir o acesso a recursos pagos ou redirecioná-lo para a página de preços caso não seja:
// middleware.js import { NextResponse } from 'next/server'; // Funções auxiliares async function isValidSession(sessionToken) { … } async function isPaidUser(sessionToken) { … } export async function middleware(request) { const { pathname } = request.nextUrl; // Caminhos para o painel de controle e página de preços const dashboardPath = '/dashboard'; const pricingPath = '/pricing'; // Verifique se o usuário está tentando acessar o painel ou qualquer área de recursos pagos if (path.startsWith(dashboardPath) || path.startsWith('/paid-features')) { // Obtenha o cookie da sessão const session = request.cookies.get('session')?.value; // Se a sessão não for válida, redirecione para login if (!session || !(await isValidSession(session))) { return NextResponse.redirect(new URL('/login', request.url)); } // Verifique se o usuário é um usuário pagante if (!(await isPaidUser(session))) { // Se não for um usuário pagante, redirecione para a página de preços return NextResponse.redirect(new URL(pricingPath, request.url)); } // Se o usuário tiver uma sessão válida e for um usuário pagante, permita o acesso return NextResponse.next(); } // Para outros caminhos, continue com a solicitação return NextResponse.next(); }
Esta vulnerabilidade de middleware dá aos invasores uma maneira de ignorar essas verificações e acessar rotas protegidas em seu aplicativo, basicamente permitindo que usem recursos pagos sem pagar.
Como a vulnerabilidade funciona
A vulnerabilidade gira em torno do cabeçalho x-middleware-subrequest
, que é destinado a prevenir recursão infinita de middleware. Ao adicionar manualmente este cabeçalho com o valor correto, um invasor pode enganar o Next.js fazendo-o pensar que o middleware já foi executado cinco vezes, quando na verdade não foi executado nenhuma vez.
Como corrigir e evitar a vulnerabilidade
Atualize para a versão mais recente do Next.js (v15). Se não puder atualizar, adicione verificações de segurança extras diretamente dentro das rotas protegidas. Por exemplo, em uma página de administração, faça:
import { getServerSession } from 'next-auth/next'; import { authOptions } from '@/app/api/auth/[...nextauth]/route'; import { redirect } from 'next/navigation'; export default async function DashboardPage() { const session = await getServerSession(authOptions); // Verificação da sessão if (!session) { redirect('/api/auth/signin'); } // Verificação de integridade da sessão const isSessionValid = verifySessionIntegrity(session); if (!isSessionValid) { redirect('/api/auth/signout?error=session-integrity'); } return ( … ); } // Função auxiliar async function verifySessionIntegrity(session) { // Verifique sinais de adulteração da sessão if (!session.user?.email || !session.user?.id) return false; // Compare com o registro do banco de dados para consistência const userRecord = await getUserFromDb(session.user.id); if (!userRecord) return false; return true; }
A vulnerabilidade é séria para aplicativos que expõem dados sensíveis, como relatórios internos ou documentos confidenciais, que não estão estritamente vinculados a uma conta de usuário.