Wenn du eine App mit Cursor, Lovable oder v0 veröffentlichst, antwortet der Server auf jede Anfrage mit einer Reihe von HTTP-Headern: unsichtbaren Anweisungen, die der Browser befolgt, bevor er irgendetwas darstellt. Eine Handvoll davon entscheidet über einen guten Teil der Sicherheit deiner Website, und fast kein Template liefert sie aktiviert mit. Dieser Guide erklärt, was jeder tut, welchen Wert du setzt, welche Fehler Dinge kaputt machen und wie du sie auf Vercel, Next.js, Nuxt, Netlify, Cloudflare oder nginx konfigurierst.
Was ein Header ist und wie du deine siehst
Ein Header ist eine Textzeile, die mit der Antwort mitreist, in der Form Name: Wert. Der Browser liest sie und ändert sein Verhalten: ein Skript laden oder nicht, HTTPS erzwingen, deine Seite in einem iframe erlauben oder nicht. Du siehst sie in den Entwicklertools (F12, Tab Network, Klick auf das Hauptdokument, Abschnitt Response Headers) oder im Terminal:
curl -I https://deinedomain.de
Tauchen die unten genannten in dieser Liste nicht auf, sind sie nicht konfiguriert. Es gibt keine Standardwerte, die dich retten.
Die sieben, die zählen
Content-Security-Policy (CSP)
Die Königin. Sie sagt dem Browser, von welchen Herkünften er Skripte, Styles, Bilder, Schriften und Verbindungen laden darf. Schafft es ein Angreifer, ein <script> in deine Seite zu injizieren, verhindert eine solide CSP, dass es ausgeführt wird. Ein ehrlicher Ausgangspunkt für eine moderne App:
Content-Security-Policy: default-src 'self'; script-src 'self' https://js.stripe.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://*.supabase.co; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
Der klassische Fehler ist 'unsafe-inline' in script-src, weil „es sonst nicht läuft": Das wirft den Hauptschutz weg. Moderne Frameworks lösen Inline-Skripte mit einer Nonce (einem Zufallswert pro Anfrage) oder mit Hashes. Und der sichere Start ist der Berichtsmodus: Der Header Content-Security-Policy-Report-Only blockiert nichts, er erzählt dir nur, was er blockieren würde. Lass ihn ein paar Tage so, sieh dir die Berichte an und wechsle zum echten Header, sobald nichts mehr kaputtgeht.
Strict-Transport-Security (HSTS)
Zwingt den Browser, für die angegebene Zeit HTTPS zu nutzen, selbst wenn der Nutzer http:// tippt oder auf einen alten Link klickt. Verhindert, dass jemand im selben Netz die Verbindung herabstuft. Der übliche Wert:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Aktiviere ihn erst, wenn deine gesamte Domain samt Subdomains über HTTPS läuft: Setzt du ihn mit einer Subdomain noch auf HTTP, sperrst du sie in jedem Browser, der den Header gesehen hat, für ein Jahr aus. Beginne im Zweifel mit einem kurzen max-age.
X-Frame-Options und frame-ancestors
Sie verhindern, dass deine Website in einem <iframe> einer anderen Seite geladen wird. Ohne sie kann jemand deine App in eine gefälschte Seite einbetten und Nutzer dazu bringen, dort zu klicken, wo sie nicht sollten: Clickjacking. X-Frame-Options: DENY oder SAMEORIGIN löst das in älteren Browsern; die moderne Form ist die Direktive frame-ancestors in der CSP. Setze beide.
X-Content-Type-Options
Ein einziger Wert: nosniff. Er verhindert, dass der Browser den Typ einer Datei errät und als Skript ausführt, was du als Text oder Bild ausgeliefert hast. Eine Zeile; es gibt keine Entschuldigung, sie auszulassen.
Referrer-Policy
Steuert, wie viel von der Herkunfts-URL gesendet wird, wenn man zu einer anderen Seite navigiert oder eine externe Ressource lädt. Ohne Kontrolle können private Pfade oder Tokens in der URL durchsickern. strict-origin-when-cross-origin ist die vernünftige Balance: deine Domain ja, der vollständige Pfad nein.
Permissions-Policy
Erklärt, welche Browserfunktionen deine Seite und ihre iframes nutzen dürfen: Kamera, Mikrofon, Standort, Zahlungen. Nutzt du sie nicht, schalte sie ab; dann kann sie auch ein injiziertes Skript oder ein Drittanbieter-iframe nicht nutzen. Zum Beispiel: camera=(), microphone=(), geolocation=().
Cross-Origin-Opener-Policy
Weniger bekannt: Isoliert dein Fenster von denen, die es geöffnet haben oder die du mit window.open geöffnet hast, und unterbindet so eine Familie von Angriffen zwischen Tabs. same-origin ist der übliche Wert, es sei denn, du bist auf Popups von Drittanbietern angewiesen (manche OAuth-Logins), dann passt same-origin-allow-popups.
Die, die du entfernen solltest
X-Powered-By und ein Server-Header mit Version verraten deinen exakten Stack jedem, der nach bekannten Lücken sucht. In Next.js entfernst du ihn mit poweredByHeader: false; in Express mit app.disable('x-powered-by'). Und X-XSS-Protection ist veraltet: Moderne Browser ignorieren ihn und in alten verursachte er selbst Fehler. Setze ihn nicht, oder setze ihn auf 0.
So setzt du sie je nach Hoster
Vercel, für jedes Framework, in vercel.json:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "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=()" }
]
}
]
}
Next.js: die Funktion headers() in next.config.js mit derselben Liste; die CSP mit Nonce wird in der Middleware erzeugt. Nuxt: routeRules in nuxt.config.ts mit einem headers-Objekt, oder ein Server-Plugin, wenn du eine Nonce brauchst. Netlify: eine Datei _headers im veröffentlichten Ordner:
/*
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Cloudflare: Transformationsregeln für Antwort-Header im Dashboard, ohne Code anzufassen. nginx auf einem VPS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Die CSP lasse ich in diesen Blöcken absichtlich weg: Sie ist die einzige, die davon abhängt, welche Skripte und Dienste deine App nutzt, und sie sollte im Berichtsmodus aufgebaut werden, bevor du sie festlegst.
Fehler, die Dinge kaputt machen
- HSTS, bevor alles auf HTTPS läuft. Sperrt jeden aus, der noch eine Subdomain auf HTTP hat. Erst prüfen, dann aktivieren.
- CSP ohne Nonce in Next.js oder Nuxt. Beide injizieren Inline-Skripte zum Hydrieren der Seite; ohne Nonce blockiert eine strikte CSP sie und die App bleibt weiß. Nutze den Nonce-Mechanismus des Frameworks.
- Header nur auf dem HTML. API-Routen und statische Dateien brauchen sie auch, vor allem
nosniff. Wende die Regel auf/(.*)an. - Doppelte Header. Fügen CDN und App denselben hinzu, behält der Browser vielleicht den strengsten oder ignoriert beide. Entscheide dich für eine Stelle.
- Subdomains vergessen (app., api., docs.): Jede antwortet mit ihren eigenen Headern.
Prüfe sie von außen
Diese Header sind öffentliche Information: Jeder kann sie lesen, auch du. Der kostenlose Security-Header-Checker listet dir in Sekunden die fehlenden und falsch gesetzten auf. Und Scanaris macht die komplette schreibgeschützte Prüfung, mit rund 45 weiteren Dingen, und gibt dir für jeden fehlenden Header einen Fix-Prompt für deine KI mit der exakten Zeile für deinen Hoster. Es nutzt nichts aus und fasst deinen Server nicht an: Es liest und sagt dir, was du einschalten sollst. Den vollständigen Kontext findest du im Sicherheitsguide für KI-gebaute Apps und in der Launch-Checkliste.
Häufig gestellte Fragen
Machen Header die Website langsamer?
Nein. Es sind ein paar hundert Bytes pro Antwort, und der Browser verarbeitet sie in Mikrosekunden. HSTS beschleunigt sie sogar, weil es bei späteren Besuchen die Weiterleitung von HTTP auf HTTPS spart.
Was, wenn ein Header in der Produktion etwas kaputt macht?
Entferne oder lockere ihn und deploye neu: Die Wirkung ist sofort da, außer bei HSTS, das Browser für die Dauer von max-age speichern. Deshalb wird die CSP im Berichtsmodus getestet und HSTS zuletzt aktiviert.
Brauche ich eine CSP, wenn meine App klein ist?
Hat deine App ein Formular oder zeigt sie Nutzerinhalte, ja: Sie ist die Verteidigung, die ein XSS zu einem kleinen Zwischenfall macht. Fang mit den übrigen Headern an, die trivial sind, und ergänze die CSP im Berichtsmodus, sobald du einen Nachmittag dafür hast.