FRAMESCAN
← Blog

Next.js CVE-2026-44573 (and related bypasses) fixed in 15.5.16

FrameScan · 2026-07-22

TL;DR

At-a-glance

ID Impact Severity Affected versions Fixed version
CVE-2026-44573 Requests can skip middleware in Pages Router i18n flows high >=12.2.0,<15.5.16 15.5.16
CVE-2026-44574 Dynamic route param tricks can bypass middleware/proxy high >=15.4.0,<15.5.16 15.5.16
CVE-2026-44575 App Router segment-prefetch paths bypass protections high >=15.2.0,<15.5.16 15.5.16

CVE-2026-44573 — Next.js Pages Router i18n middleware/proxy bypass

Attackers could reach routes you expect to be gated by middleware or a reverse proxy rule by leveraging i18n routing behavior. This can expose protected pages or internal endpoints. Treat as high priority if you rely on middleware for auth, geo, or IP rules in Pages Router with i18n.

Technical details

Based on the advisory, certain i18n paths in the Pages Router could allow requests to slip past middleware or proxy checks. The safe pattern is to normalize and enforce checks on the canonical pathname and not rely on locale-prefixed variants alone. Ensure the middleware runs for all locale variants and that proxy rules account for i18n prefixes.

Illustrative example — not Next.js source:

Vulnerable pattern (middleware fails to normalize locales and unintentionally skips checks for some locale paths):

// middleware.js (illustrative example)
import { NextResponse } from 'next/server';

export function middleware(req) {
  const url = new URL(req.url);

  // Only enforce auth on non-prefixed paths; locale-prefixed paths bypass unintentionally
  if (!url.pathname.startsWith('/en') && !url.pathname.startsWith('/es')) {
    if (!req.headers.get('x-user-authenticated')) {
      return NextResponse.redirect(new URL('/login', url));
    }
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/((?!_next|api/public).*)'],
};

Fixed pattern (normalize locale and apply the same rule regardless of locale prefix):

// middleware.js (illustrative example — fixed)
import { NextResponse } from 'next/server';

function stripLocale(pathname) {
  // Example locales; align with your i18n config
  const locales = ['en', 'es', 'fr'];
  const parts = pathname.split('/').filter(Boolean);
  if (parts.length > 0 && locales.includes(parts[0])) {
    return '/' + parts.slice(1).join('/');
  }
  return pathname;
}

export function middleware(req) {
  const url = new URL(req.url);
  const canonicalPath = stripLocale(url.pathname) || '/';

  const isPublic = canonicalPath.startsWith('/login') || canonicalPath.startsWith('/public');
  if (!isPublic && !req.headers.get('x-user-authenticated')) {
    return NextResponse.redirect(new URL('/login', url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/((?!_next|api/public).*)'],
};

CVE-2026-44574 — Next.js dynamic route parameter injection bypass

An attacker might craft route parameters to slip past middleware or proxy conditions, potentially reaching endpoints that should require authentication or internal access. Prioritize this if you depend on middleware for route-level access control in dynamic routes.

Technical details

The advisory describes a bypass via dynamic route parameter injection. The robust approach is to validate and normalize parameters before applying access decisions, and to avoid building security decisions from untrusted path segments alone. Use strict matchers and server-side validation.

Illustrative example — not Next.js source:

Vulnerable pattern (auth check keyed off an unvalidated dynamic parameter):

// middleware.js (illustrative example)
import { NextResponse } from 'next/server';

export function middleware(req) {
  const url = new URL(req.url);
  const segments = url.pathname.split('/').filter(Boolean);
  const project = segments[1]; // e.g., /projects/[project]

  // Unsafe: treating certain project names as public based on the raw param
  const isPublicProject = project === 'public' || project?.startsWith('demo-');
  if (!isPublicProject && !req.headers.get('x-user-authenticated')) {
    return NextResponse.redirect(new URL('/login', url));
  }
  return NextResponse.next();
}

Fixed pattern (server-side validation of params and explicit allowlist):

// middleware.js (illustrative example — fixed)
import { NextResponse } from 'next/server';

const PUBLIC_PROJECTS = new Set(['public']);

function isPublicProject(param) {
  // Only allow exact, known-safe identifiers
  return PUBLIC_PROJECTS.has(param);
}

export function middleware(req) {
  const url = new URL(req.url);
  const parts = url.pathname.split('/').filter(Boolean);
  const project = parts[1] || '';

  const isPublic = isPublicProject(project) || url.pathname.startsWith('/login');
  if (!isPublic && !req.headers.get('x-user-authenticated')) {
    return NextResponse.redirect(new URL('/login', url));
  }
  return NextResponse.next();
}

CVE-2026-44575 — Next.js App Router segment-prefetch bypass

Requests using segment-prefetch routes in the App Router could avoid middleware or proxy protections, opening a path to resources you intended to protect. If you rely on App Router middleware for auth or request filtering, treat this as high urgency.

Technical details

Per the advisory, certain segment-prefetch routes can cause middleware/proxy to be skipped. A safer pattern is to avoid treating any prefetch-style path or hint as inherently safe; perform the same checks regardless of request source and ensure your matcher includes the relevant patterns.

Illustrative example — not Next.js source:

Vulnerable pattern (skipping checks for suspected prefetch requests):

// middleware.js (illustrative example)
import { NextResponse } from 'next/server';

export function middleware(req) {
  const url = new URL(req.url);

  // Incorrectly trust prefetch-like paths or hints
  if (url.searchParams.get('prefetch') === '1') {
    return NextResponse.next();
  }

  if (!req.headers.get('x-user-authenticated')) {
    return NextResponse.redirect(new URL('/login', url));
  }
  return NextResponse.next();
}

Fixed pattern (apply auth consistently, regardless of prefetch indicators):

// middleware.js (illustrative example — fixed)
import { NextResponse } from 'next/server';

export function middleware(req) {
  const url = new URL(req.url);

  const isPublic = url.pathname.startsWith('/login') || url.pathname.startsWith('/assets');
  if (!isPublic && !req.headers.get('x-user-authenticated')) {
    return NextResponse.redirect(new URL('/login', url));
  }

  return NextResponse.next();
}

export const config = {
  // Ensure matchers include prefetch-related paths as applicable to your app
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};

Remediation

Call to action

Is your site exposed? Scan it for $1