Full Report
NextJS is an extremely popular 'static' site generator, which this website actually uses. So, finding configuration issues or straight up vulnerabilities in NextJS is awesome for bug hunting, since many things would be affected by it. The _next/image component is a built in image optimiziation library that is enabled by default. This works by making a request to the endpoint _next/image under the hood, which implements caching. Now, the actual server makes a request to //localhost/duck.jpg with the provided URL. There is a remotePatterns configuration that restricts the protocols and hostnames set, which is commonly set to '*'. When configured as such, this can lead to SSRF bugs with https://example.com/_next/image?url=https://localhost:2345/api/v1/x&w=256&q=75. Most of the time, this is a blind GET request but there was situations where the impact can be escalated. First, with an old version of NextJS or dangerouslyAllowSVG is set then this SSRF leads to an XSS via the image reflection on the domain. If the response doesn't have a Content-Type then the full response is leaked. Even though NextJS is a client side library, there are many crazy server side features like Server Actions. This feature allows writing JS code that is executed on the server instead of the client side to interact with. When handling redirects within the server side code, it takes in the Host header to make the request. So, by providing the Host header, it's possible to force a localhost redirect leading to SSRF. To exploit this, an action must be defined where the action redirects to some URL. To turn this into a full SSRF read, we can spoof the HEAD request to do some janky things. Set up a server that takes requests to any path. On a HEAD request return a 200 with a specific content-type to satisfy the constraints of the system. On the actual GET request, return a 302 to our victim IP. Data is returned on the request. Overall, an interesting post on a bug within NextJS and a universal exploit method as well. This is the second issue found with this functionality - the first SSRF on the image stuff was found via Sam Curry.
Analysis Summary
# Vulnerability: SSRF and XSS in Next.js Image Optimization and Server Actions
## CVE Details
- **CVE ID:** CVE-2024-34351 (referenced for the Server Action SSRF)
- **CVSS Score:** 7.5 (High) - *Estimate based on typical SSRF impact*
- **CWE:** CWE-918 (Server-Side Request Forgery), CWE-79 (Cross-Site Scripting)
## Affected Systems
- **Products:** Next.js Framework
- **Versions:**
- Versions prior to the fix for Server Action redirects (refer to vendor advisory for exact versioning, typically fixed in 14.2.3).
- All versions using `_next/image` with permissive configurations.
- **Configurations:**
- `images.remotePatterns` set to allow all hosts (e.g., `hostname: "**"`).
- `dangerouslyAllowSVG: true` (increases impact to XSS).
- Usage of **Server Actions** that perform redirects.
## Vulnerability Description
There are two primary attack vectors identified:
1. **Image Optimization SSRF:** The `_next/image` component serves as a proxy to resize images. If `remotePatterns` are misconfigured to whitelist all domains, an attacker can use the server to proxy requests to internal infrastructure (localhost).
2. **Server Action Redirect SSRF:** When a Server Action performs a redirect, Next.js may use the user-supplied `Host` header to construct the redirect URL. This allows an attacker to manipulate the header to force the server to make requests to internal metadata services or other internal hosts. By using a "janky" exploit method (responding differently to HEAD and GET requests), an attacker can bypass content-type constraints to read full internal responses.
## Exploitation
- **Status:** PoC available (Techniques documented by Assetnote)
- **Complexity:** Medium (Server Action exploitation requires specific response handling for HEAD vs GET)
- **Attack Vector:** Network
## Impact
- **Confidentiality:** High (Internal services can be queried; full responses can be leaked under specific conditions)
- **Integrity:** Medium (Potential for XSS via SVG reflection)
- **Availability:** Low
## Remediation
### Patches
- Update Next.js to the latest stable version (at least **v14.2.3** for the Server Actions fix).
### Workarounds
- **Strict Allowlisting:** In `next.config.js`, restrict `remotePatterns` to only trusted, specific domain names. Never use wildcards (`**`) for hostnames.
- **Disable SVG:** Ensure `dangerouslyAllowSVG` is set to `false` (default) to prevent XSS.
- **Header Validation:** If using older versions, implement middleware to validate the `Host` header against a known allowlist.
## Detection
- **Indicators of Compromise:**
- Frequent requests to `/_next/image?url=...` where the URL parameter contains internal IP addresses, `localhost`, or `169.254.169.254`.
- Server Action requests (`Next-Action` header present) accompanied by unexpected `Host` headers.
- **Detection methods and tools:**
- Monitor web server logs for outbound connections from the Next.js server to internal ports or unexpected external IPs.
## References
- **Vendor Advisory:** hxxps[://]github[.]com/vercel/next.js/security/advisories/GHSA-fr5h-8p8f-v8rr
- **Assetnote Research:** hxxps[://]www[.]assetnote[.]io/resources/research/digging-for-ssrf-in-nextjs-apps
- **Next.js Documentation:** hxxps[://]nextjs[.]org/docs/pages/api-reference/components/image#remotepatterns