← Zurück zum Blog
SicherheitScanaris Team · 7 Min. Lesezeit · October 04, 2026

Sicherheits-Checkliste für deine Next.js-App vor dem Start

Eine Next.js-App mit Cursor, v0 oder Bolt zu veröffentlichen geht schnell, aber die Geschwindigkeit verbirgt Lücken, die du erst siehst, wenn jemand sie für dich findet. Diese Checkliste geht durch, was du vor dem Deploy prüfen solltest, mit dem Warum jedes Punkts, wie du ihn prüfst und dem Code zum Beheben. Die Zwei-Minuten-Version steht am Ende.

Wie Next.js die Grenze zwischen Server und Client zieht

Fast jede Sicherheitslücke in Next.js ist dieselbe Lücke: Etwas, das auf dem Server bleiben sollte, ist in den Browser gewandert. Server Components laufen auf dem Server und schicken ihren Code nie an den Client; sobald eine Datei 'use client' trägt, landet alles, was sie importiert, im öffentlichen Bundle. Route Handler (app/api/*/route.ts) und Server Actions sind öffentliche URLs, auch wenn du sie nie siehst. Die Middleware läuft vor allem anderen, ist aber keine Mauer. Ist diese Grenze klar, ist der Rest der Liste Routine.

1. Umgebungsvariablen: Vorsicht mit NEXT_PUBLIC

Warum es wichtig ist. Alles, was mit NEXT_PUBLIC_ beginnt, wird beim Build ins Browser-JavaScript eingebacken. Jeder kann es mit den Entwicklertools lesen. Leg dort nie einen privaten API-Key, ein Service-Token oder dein Datenbank-Secret ab.

So prüfst du es. Öffne deine .env und dein Vercel-Dashboard und lies jede Variable mit öffentlichem Präfix mit der Frage: Würde etwas passieren, wenn ich sie auf Twitter poste? Lautet die Antwort ja, entferne das Präfix und verschiebe sie auf den Server.

So behebst du es. Variablen ohne Präfix existieren nur auf dem Server: Lies sie aus Server Components, Route Handlern oder Server Actions. Damit ein Modul mit Secrets nie aus einer Client-Komponente importiert werden kann, setze import 'server-only' in seine erste Zeile: Importiert es jemand von der falschen Seite, schlägt der Build fehl, statt den Key zu leaken. Mehr dazu in den Secrets, die deine App im Browser preisgibt.

2. Route Handler und Server Actions: immer validieren und autorisieren

Warum es wichtig ist. Eine API-Route ist nicht privat, weil sie in deinem Ordner liegt. Sie ist eine öffentliche URL, die jeder mit curl aufrufen kann. Und eine Server Action, auch wenn sie von einem Button ausgelöst wird, ebenso: Next.js stellt sie als POST-Endpoint mit einer Kennung bereit. Dass ein Button für einen Nutzer ausgeblendet ist, hindert niemanden daran, den Endpoint direkt anzusprechen.

So behebst du es. Prüfe Session und Berechtigungen in jedem Handler und jeder Action, nicht nur in der Oberfläche. Validiere den Request-Body mit einem Schema (zod oder ähnlich), bevor du die Datenbank anfasst. Übernimm die Nutzer-ID nie vom Client: Hol sie aus der Session. Und begrenze die Rate für alles, was Geld kostet oder E-Mails verschickt.

// app/actions/update-profile.ts
'use server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'

const Schema = z.object({ name: z.string().min(1).max(80) })

export async function updateProfile(input: unknown) {
  const session = await getSession()
  if (!session) throw new Error('Unauthorized')
  const data = Schema.parse(input)
  // session.user.id verwenden, nie eine ID vom Client
  await db.user.update({ where: { id: session.user.id }, data })
}

3. Die Middleware ist nicht deine einzige Authentifizierung

Warum es wichtig ist. Es ist verlockend, ganz /dashboard aus middleware.ts heraus zu schützen und es dabei zu belassen. Im März 2025 wurde CVE-2025-29927 veröffentlicht: Ein interner Header (x-middleware-subrequest) erlaubte es, die Middleware in betroffenen Versionen komplett zu überspringen, und mit ihr jede Session-Prüfung, die nur dort lebte. Behoben in Next.js 15.2.3 und 14.2.25 (mit Patches für 13 und 12), aber die Lektion bleibt.

So behebst du es. Aktualisiere Next.js auf eine gepatchte Version und nutze die Middleware als erste Schicht (wer keine Session hat, wird umgeleitet), nie als einzige. Die Prüfung, die die Daten wirklich schützt, gehört in die Seite, den Handler oder die Action, die sie ausliefert.

4. Sicherheits-Header

Warum es wichtig ist. Standardmäßig sendet Next.js keine defensiven Header. Ohne sie ist deine App offen für Clickjacking, dafür, dass der Browser als Skript ausführt, was keines ist, und für Downgrade auf HTTP.

So behebst du es. In next.config.js:

// next.config.js
const securityHeaders = [
  { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
  { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
  { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
]

module.exports = {
  poweredByHeader: false,
  productionBrowserSourceMaps: false,
  async headers() {
    return [{ source: '/(.*)', headers: securityHeaders }]
  },
}

Die Content-Security-Policy verdient eine eigene Behandlung: Next.js injiziert Inline-Skripte zum Hydrieren der Seite, also braucht eine strikte CSP eine Nonce, die in der Middleware erzeugt und an die Komponenten weitergereicht wird. Beginne im Modus Report-Only. Die Details zu jedem Header stehen in HTTP-Sicherheits-Header erklärt.

5. Secrets, die in Client Components wandern

Warum es wichtig ist. Ein privater Key landet leicht aus Versehen in einer Client-Komponente, vor allem wenn die KI Dateien umschreibt und Imports verschiebt. Taucht er im ausgelieferten JavaScript auf, ist er bereits kompromittiert.

So prüfst du es. Nach next build suchst du in .next/static nach Strings wie sk_live, service_role, sk-ant oder Webhook-URLs. Tauchen sie auf, rotiere sie und verschiebe sie auf den Server, mit import 'server-only' als Absicherung.

6. Remote-Bilder und Anfragen an Nutzer-URLs

Warum es wichtig ist. next/image optimiert Bilder über deinen Server. Erlaubst du in images.remotePatterns jeden Host, kann jeder deinen Server als Bild-Proxy nutzen und dein Kontingent verbrauchen. Dasselbe gilt für eine API-Route, die die vom Nutzer übergebene URL herunterlädt: Sie kann auf interne Dienste deiner Infrastruktur zeigen (SSRF).

So behebst du es. Beschränke remotePatterns auf die Domains, die du wirklich nutzt. Muss eine Route externe URLs laden, prüfe das Protokoll (nur https), lehne private IPs und interne Hostnamen ab und setze ein Zeitlimit.

7. Offene Weiterleitungen

Warum es wichtig ist. Das klassische redirect(searchParams.next) nach dem Login erlaubt es, Links auf deiner Domain zu bauen, die auf einer Phishing-Seite enden: deinedomain.de/login?next=https://boese.example.

So behebst du es. Akzeptiere nur relative Pfade, die mit / beginnen (und nicht mit //), oder vergleiche mit einer Liste erlaubter Ziele.

8. Dateien, die nicht erreichbar sein sollten

Warum es wichtig ist. Alles in public/ wird unverändert ausgeliefert: Eine versehentlich dorthin kopierte .env, ein Datenbank-Dump oder eine service-account.json sind nur eine URL entfernt. Und Source Maps in der Produktion erlauben es, deinen Client-Code mit Originalnamen zu lesen.

So prüfst du es. Probiere deinedomain.de/.env, /.git/HEAD und öffne eine JS-Datei aus dem Bundle, um zu sehen, ob sie mit einer Zeile sourceMappingURL endet, die auf eine erreichbare .map zeigt. Betrachte den Ordner public/ mit den Augen eines Fremden.

9. Session-Cookies und Auth-Bibliotheken

Warum es wichtig ist. Auth.js (NextAuth), Clerk oder Supabase mit seinem Server-Paket konfigurieren Cookies standardmäßig korrekt. Was schiefgeht, ist, was du selbst hinzufügst: ein eigenes Cookie ohne HttpOnly, ein schwaches oder aus einem Tutorial kopiertes AUTH_SECRET, oder die Session im localStorage.

So behebst du es. Erzeuge das Secret mit openssl rand -base64 32, speichere es ohne öffentliches Präfix, und nutze für jedes eigene Cookie Secure, HttpOnly und SameSite=Lax.

10. Abhängigkeiten und die Next.js-Version

Warum es wichtig ist. Deine App schleppt hunderte Pakete mit, und Next.js selbst veröffentlicht mehrmals im Jahr Sicherheitskorrekturen. Der Middleware-Fall von 2025 traf alle, die nicht aktualisierten.

So behebst du es. npm audit vor jedem Deploy, Dependabot oder Renovate im Repository, und eine einfache Regel: Next.js im selben Monat aktualisieren, in dem ein Sicherheitspatch erscheint.

Deployment auf Vercel: drei Details

  • Umgebungen. Variablen haben einen Geltungsbereich (Production, Preview, Development). Gib Preview-Deployments keine Produktions-Credentials: Ein Preview ist eine öffentliche URL mit deinem neuesten Code.
  • Preview-Schutz. Aktiviere Deployment Protection, damit Preview-URLs einen Vercel-Login verlangen; sonst sieht jeder mit dem Link den laufenden Branch.
  • Header. Die aus next.config.js gelten auf Vercel ohne Weiteres; nutzt du zusätzlich vercel.json, dupliziere sie nicht.

Deine 2-Minuten-Checkliste

  • Keine NEXT_PUBLIC_-Variable enthält ein Secret; Module mit Keys tragen import 'server-only'.
  • Jeder Route Handler und jede Server Action prüft die Session und validiert die Eingabe; die Nutzer-ID kommt aus der Session.
  • Next.js in einer gepatchten Version; die Middleware ist nicht die einzige Auth-Schicht.
  • Sicherheits-Header in next.config.js; poweredByHeader: false; CSP mindestens im Berichtsmodus.
  • Bundle ohne sk_live, service_role und Webhooks; Source Maps aus.
  • remotePatterns eingeschränkt; nichts lädt Nutzer-URLs ohne Validierung.
  • Weiterleitungen nur auf relative Pfade.
  • public/ ohne sensible Dateien; .env und .git nicht erreichbar.
  • Cookies mit Secure, HttpOnly und SameSite; zufälliges AUTH_SECRET.
  • npm audit sauber; Previews geschützt und ohne Produktions-Secrets.

Prüfe das alles in 30 Sekunden

Diese Liste bei jedem Deploy von Hand durchzugehen ist mühsam und wird vergessen. Scanaris führt schreibgeschützte Prüfungen auf deiner veröffentlichten Website durch: Header, im JavaScript exponierte Secrets, erreichbare sensible Dateien, Source Maps, Cookies und CORS. Jeder Fund kommt mit einem Prompt zum Einfügen in Cursor oder v0 mit der exakten Korrektur für Next.js. Lässt du das Monitoring an, meldet es sich, wenn eine Vibe-Coding-Session wieder etwas öffnet. Zum Vertiefen gibt es die Sicherheitsseite für Next.js und die allgemeine Launch-Checkliste.

Häufig gestellte Fragen

Sind Server Actions standardmäßig sicher?

Sie sind bequemer als eine API-Route, nicht sicherer. Next.js stellt sie als öffentliche Endpoints bereit; Authentifizierung und Validierung baust du in jede einzelne selbst ein.

Schützt die Middleware meine Routen?

Sie taugt für Weiterleitungen und günstige Prüfungen, darf aber nicht die einzige Barriere sein. Seit dem Fall von 2025 gilt: Die Session auch dort prüfen, wo die Daten ausgeliefert werden.

Brauche ich eine CSP mit Next.js?

Ja, aber mit Nonce und zunächst im Berichtsmodus. Ohne Nonce blockiert eine strikte CSP die Inline-Skripte des Frameworks selbst und die Seite bleibt weiß.

Wie steht deine Website da?

Lass Scanaris drüberlaufen und prüf es in 30 Sekunden, kostenlos.

Meine Website scannen

Verwandte Checks

Sicherheits-Guides für deinen Stack