CVE-2024-34351: Insufficient Information (NVD-CWE-noinfo)
value: Next.js is a React framework that can provide building blocks to create web applications. A Server-Side Request Forgery (SSRF) vulnerability was identified in Next.js Server Actions. If the `Host` header is modified, and the below conditions are also met, an attacker may be able to make requests that appear to be originating from the Next.js application server itself. The required conditions are 1) Next.js is running in a self-hosted manner; 2) the Next.js application makes use of Server Actions; and 3) the Server Action performs a redirect to a relative path which starts with a `/`. This vulnerability was fixed in Next.js `14.1.1`.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-05-14T15:38Z
Repository: https://github.com/vercel/next.js
Language: TypeScript
Files changed: packages/next/src/server/app-render/action-handler.ts, packages/next/src/server/lib/start-server.ts
Commit date: 2024-02-27 09:17:50 -0800
Commit message: Improve redirection handling (#62561)

Currently to redirect to another RSC route of the same app, we initiate
another request to that route. This PR changes that request to directly
use the internal hostname of the current server handler, rather than
relying on other headers.

Closes NEXT-2614
Diff: diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts
index 7bf38dfdc2..c1f0dadf95 100644
--- a/packages/next/src/server/app-render/action-handler.ts
+++ b/packages/next/src/server/app-render/action-handler.ts
@@ -177,13 +177,17 @@ async function createRedirectRenderResult(
     }
 
     const forwardedHeaders = getForwardedHeaders(req, res)
     forwardedHeaders.set(RSC_HEADER, '1')
 
-    const host = originalHost.value
     const proto =
       staticGenerationStore.incrementalCache?.requestProtocol || 'https'
+
+    // For standalone or the serverful mode, use the internal hostname directly
+    // other than the headers from the request.
+    const host = process.env.__NEXT_PRIVATE_HOST || originalHost.value
+
     const fetchUrl = new URL(
       `${proto}://${host}${basePath}${parsedRedirectUrl.pathname}`
     )
 
     if (staticGenerationStore.revalidatedTags) {
diff --git a/packages/next/src/server/lib/start-server.ts b/packages/next/src/server/lib/start-server.ts
index 018f0da49c..1f5734e900 100644
--- a/packages/next/src/server/lib/start-server.ts
+++ b/packages/next/src/server/lib/start-server.ts
@@ -244,10 +244,11 @@ export async function startServer(
         )
       }
 
       // expose the main port to render workers
       process.env.PORT = port + ''
+      process.env.__NEXT_PRIVATE_HOST = `${actualHostname}:${port}`
 
       // Only load env and config in dev to for logging purposes
       let envInfo: string[] | undefined
       let expFeatureInfo: string[] | undefined
       if (isDev) {

Vulnerable code:     const host = originalHost.value
Fixed code: 
    // For standalone or the serverful mode, use the internal hostname directly
    // other than the headers from the request.
    const host = process.env.__NEXT_PRIVATE_HOST || originalHost.value

      process.env.__NEXT_PRIVATE_HOST = `${actualHostname}:${port}`