Critical Vulnerability in Next.js Framework Exposes Websites to Cache Poisoning and XSS Attacks

A recent deep dive into the Next.js ecosystem has uncovered critical vulnerabilities, including cache poisoning and stored cross-site scripting (XSS) attacks, sparking significant discussions within the cybersecurity community.

These exploits, affecting versions of Next.js between 13.5.1 and 14.2.9, highlight the risks associated with improper caching mechanisms in one of the most widely used JavaScript frameworks.

Below are the technical findings and implications of this research, which emphasize the importance of securing Next.js deployments.

The research sheds light on how internal behaviors of Next.js, such as data-fetching routes and the transmission of request details using getStaticProps (SSG) and getServerSideProps (SSR), can be manipulated.

When caching misconfigurations occur, attackers can perform cache poisoning that results in significant damage to web applications.

Cache Poisoning for Denial of Service (DoS)

By appending specific parameters (e.g., __nextDataReq) and headers (x-now-route-matches) to requests, attackers can poison server-side caches.

This manipulation tricks the framework into treating dynamic SSR data as static SSG data, forcing it to cache restricted content with long expiration times.

Consequently, users accessing legitimate pages are served corrupted content, causing service disruptions.

For example:

  • A regular /poc page request returns valid HTML content.
  • Adding __nextDataReq with the correct configuration forces a JSON object (pageProps) to be served.
  • Poisoning occurs when the attacker combines such parameters and headers during a cache refresh interval, effectively overriding expected content.

Stored XSS via Cache Poisoning

Stored XSS is a critical vulnerability where malicious scripts are stored on the server and executed in users’ browsers.

By exploiting Next.js’s reflection of user-provided data (e.g., User-Agent, cookies, headers) via getServerSideProps, an attacker can inject harmful payloads into the cached content.

Stored XSS on Next.js

If the poisoned response is served with a text/html content type, the malicious payload will execute whenever users access the affected page without requiring further interaction.

Example payload:

GET /poc?__nextDataReq=1 HTTP/1.1
User-Agent: CP TO SXSS ON NEXT.JS : <img src=x onerror=alert('Exploit')>
x-now-route-matches: 1

An identified vulnerability, CVE-2024-46982, demonstrates how the interplay between caching directives (s-maxage and stale-while-revalidate) can be exploited to cache sensitive server-side data that should remain private.

According to the research, by tricking the framework into treating an SSR request as an SSG request, attackers can bypass default caching controls (no-cache).

This misclassification allows private data to be cached and reused, jeopardizing confidentiality.

Vulnerabilities impact static-route deployments using the Pages Router in Next.js on non-Vercel-hosted sites.

Patching to Next.js 14.2.10 or later versions is critical.Modifying cache keys to include dynamic request details (e.g., parameters, headers) ensures cache integrity.

Disabling stale-while-revalidate mechanisms for dynamic content prevents improper cache revalidation.

Conduct thorough code reviews for getServerSideProps implementations to ensure sensitive user data isn’t improperly reflected or cached.

Next.js’s popularity, with over 6 million weekly downloads, underscores the widespread impact of these vulnerabilities, potentially affecting availability and user privacy on sensitive platforms.

While the Vercel team has released timely patches and security advisories, organizations relying on Next.js must prioritize applying these updates and securing their implementations against advanced exploitation techniques.

For ethical hackers, this research serves as a reminder to test responsibly, ensuring minimal disruption during vulnerability assessments.

Also Read:

Recent Articles

Related Stories

LEAVE A REPLY

Please enter your comment!
Please enter your name here