Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
Tools/GitHubGitHub/nayekah/next.js-proof-of-concept
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityLearning & EducationLabs & Practice
GitHubnayekah/next.js-proof-of-concept

Next.js-Proof-of-Concept

Some Proof-of-Concept (POCs) for CVE-2025-29927, CVE-2026-27978, and CVE-2026-29057 in Next.js.

View Repository
15 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Next.js CVE Proof of Concept

This repository contains reproducible proof-of-concept environments for three Next.js vulnerabilities. Each PoC includes a vulnerable target, a fixed target, and a script that demonstrates the behavioral difference between the two.

The goal of this project is to make the root cause and practical impact of each issue easy to observe in a minimal environment.

Included Vulnerabilities

CVEAdvisoryImpactVulnerable VersionFixed Version
CVE-2025-29927GHSA-f82v-jwr5-mffwauthorization bypass when access control relies only on middleware15.2.215.2.3
CVE-2026-27978GHSA-mq59-m269-xvcxOrigin: null bypass of Server Actions CSRF checks16.1.616.1.7
CVE-2026-29057GHSA-ggv3-7p47-pfv8HTTP request smuggling through rewrites to an external backend15.5.1215.5.13
NEXT-16.2.4-IMAGE-REDIRECTlocal source audit findingimage optimizer remote allowlist bypass through redirects16.2.4not verified
NEXT-16.2.4-IMAGE-LOCAL-REWRITElocal source audit findingimage optimizer local URL can reach private upstream through external rewrites16.2.4not verified

Release Commits and Patch Commits

The hashes below are taken from upstream vercel/next.js.

CVEVulnerable Release CommitFixed Release CommitRelevant Patch Commit
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

Repository Layout

.
|- 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

Prerequisites

  1. Install Docker Desktop or Docker Engine.
  2. Ensure docker compose is available.
  3. Run commands from the root of this repository.

Start All Services

docker compose up --build

Exposed ports:

  • 3001 -> CVE-2025-29927 vulnerable
  • 3002 -> CVE-2025-29927 fixed
  • 3003 -> CVE-2026-27978 vulnerable
  • 3004 -> CVE-2026-27978 fixed
  • 3005 -> CVE-2026-29057 vulnerable
  • 3006 -> CVE-2026-29057 fixed
  • 3007 -> NEXT-16.2.4-IMAGE-REDIRECT
  • 3008 -> NEXT-16.2.4-IMAGE-LOCAL-REWRITE

Reproduce 1: CVE-2025-29927

Vulnerable Code Path

In this PoC, /dashboard is protected only by middleware:

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()
}

The authorization check itself is not incorrect. The issue is that the route depends entirely on the assumption that middleware execution cannot be skipped.

In affected Next.js versions, external requests could still supply the internal header x-middleware-subrequest, and the runtime treated that value as trusted middleware metadata. The relevant vulnerable logic was:

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 was not filtered there, so attacker-controlled input could reach the middleware runtime. That value was then used to derive recursion depth:

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',
      },
    }),
  }
}

If an attacker sends middleware:middleware:middleware:middleware:middleware, the runtime may conclude that recursion depth has already been reached and forward the request without executing the application middleware.

Run

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

Expected behavior:

  • 3001 returns a redirect without the exploit header, but returns 200 OK with x-middleware-subrequest.
  • 3002 continues to redirect to /login because the internal header is no longer trusted from external input.

Reproduce 2: CVE-2026-27978

Vulnerable Code Path

This PoC exposes a normal Server Action that changes server-side state:

'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('/')
}

The issue is not in transferFunds() itself. The vulnerable behavior was in Next.js CSRF validation for Server Actions. In affected versions, Origin: null was treated like a missing origin instead of an explicit opaque origin:

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.')
    // ...
  }
}

Because 'null' became undefined, requests from opaque origins such as sandboxed iframes could avoid the host/origin comparison path and still be processed with victim cookies attached.

Run

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

Expected behavior:

  • the script logs in as the victim, extracts the generated Server Action field from the page, and submits it with Origin: null
  • on the vulnerable target, transfer state changes
  • on the fixed target, the request fails and state remains unchanged

Reproduce 3: CVE-2026-29057

Vulnerable Code Path

This PoC rewrites /rewrites/:path* to an external backend:

Download Tool