HTTP-Sicherheits-Header sind die einfachste, billigste und wirkungsvollste Härtungs-Schicht für eine Web-App — ein paar Zeilen in der Server-Konfig, und mehrere Klassen Angriffe sind blockiert oder massiv erschwert. Dieser Artikel gibt eine Übersicht über die wichtigen Header, was sie tun, was sie nicht tun, welche modern sind und welche als veraltet gelten — plus konkrete Beispiel-Konfigurationen für nginx, Caddy und Express.
Der moderne Header-Stack
Eine voll-gehärtete Response-Header-Konfig sieht in etwa so aus:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123' 'strict-dynamic'; object-src 'none'; base-uri 'self'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-originDieser Stack adressiert die Hauptklassen: Protocol-Downgrade (HSTS), XSS und Code-Injection (CSP), MIME-Confusion (nosniff), Information-Leakage (Referrer-Policy), Hardware-Permission-Missbrauch (Permissions-Policy), Spectre-Side-Channels (COOP/COEP/CORP).
Header-für-Header
| Header | Zweck | Vertieft in |
|---|---|---|
Strict-Transport-Security | HTTPS erzwingen, Downgrade verhindern | hsts-und-https-only |
Content-Security-Policy | Skript-/Ressource-Quellen einschränken (XSS-Schutz) | csp-deployment, Kap 11 |
X-Content-Type-Options | MIME-Sniffing deaktivieren | unten |
Referrer-Policy | Referer-Header bei Navigation steuern | unten |
Permissions-Policy | Browser-APIs einschränken (Kamera, Mic, etc.) | permissions-policy |
Cross-Origin-Opener-Policy | Cross-Origin-Window-Isolation | coop-coep-corp |
Cross-Origin-Embedder-Policy | Embed-Ressourcen-Anforderungen | coop-coep-corp |
Cross-Origin-Resource-Policy | Wer darf diese Ressource laden | coop-coep-corp |
Access-Control-Allow-Origin | CORS — Cross-Origin-Requests erlauben | cors |
Set-Cookie (mit Flags) | Cookie-Eigenschaften | cookie-flags-und-attribute |
X-Content-Type-Options — der schnelle Win
X-Content-Type-Options: nosniff deaktiviert das MIME-Sniffing im Browser. Ohne diesen Header rät der Browser den Content-Type anhand des Datei-Inhalts — und kann ein als text/plain ausgeliefertes File als HTML/JavaScript interpretieren, wenn der Anfang verdächtig aussieht.
Wirkung: Stored-XSS via User-Upload mit verfälschter Extension funktioniert nicht mehr, wenn der Server den korrekten Content-Type setzt und nosniff aktiv ist.
Konfiguration: ein einziger Header, immer setzen. Keine Trade-offs.
X-Content-Type-Options: nosniffReferrer-Policy — Privacy + Sicherheit
Der Referer-Header (historisch falsch geschrieben) wird vom Browser bei Navigation mitgeschickt — die URL der vorigen Seite. Ohne Steuerung leakt das:
- Session-Tokens in URLs (Anti-Pattern, aber existiert).
- Interne URLs in externe Klicks.
- Such-Queries der vorigen Seite.
Empfohlene Policy:
Referrer-Policy: strict-origin-when-cross-originWas das macht:
- Same-Origin-Requests: voller Referer (
https://app.example.com/private-page). - Cross-Origin auf HTTPS-Ziel: nur Origin (
https://app.example.com). - Cross-Origin auf HTTP-Ziel: gar nichts.
Default in modernen Browsern seit 2020 — explizit setzen schadet trotzdem nicht (Klarheit für Audit).
Alternativen:
no-referrer— niemals senden. Hart, kann Analytics brechen.origin— immer nur Origin (auch Same-Origin).same-origin— bei Cross-Origin gar nichts.
Deprecated und veraltete Header
Manche Header tauchen noch in alten Empfehlungs-Artikeln auf, sind aber nicht mehr nötig oder sogar kontraproduktiv:
| Header | Status | Was stattdessen |
|---|---|---|
X-XSS-Protection | Deprecated — alle modernen Browser ignorieren oder haben es entfernt | CSP |
X-Frame-Options | Funktioniert, aber CSP frame-ancestors ist moderner | CSP frame-ancestors |
Public-Key-Pins (HPKP) | Komplett deprecated, kein Browser unterstützt | Certificate Transparency Log (passiv) |
Expect-CT | Deprecated mit CT-Pflicht 2024 | Nichts (CT ist Default) |
Feature-Policy | Umbenannt zu Permissions-Policy | Permissions-Policy |
Hinweis zu X-Frame-Options: wenn die App noch alte Browser unterstützen muss (Stand 2026 selten), kann es als Fallback parallel zu frame-ancestors gesetzt werden. Moderne Apps brauchen nur frame-ancestors.
X-XSS-Protection bewusst weglassen: der Header hatte in alten IE/Edge-Versionen sogar gefährliche Bugs (selbst-erzeugte XSS-Lücken durch fehlerhafte Auto-Sanitization). Heute irrelevant.
Konfiguration in den wichtigsten Servern
nginx:
server {
# ... TLS-Config ...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
# CSP wird oft pro Location gesetzt, weil sie pro App unterschiedlich ist
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'" always;
# ...
}Wichtig: always lässt nginx den Header auch bei Error-Responses (4xx/5xx) setzen. Ohne always werden Header bei Error-Pages weggelassen — schlechte Default-Wahl.
Caddy:
app.example.com {
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "camera=(), microphone=(), geolocation=()"
Cross-Origin-Opener-Policy "same-origin"
Cross-Origin-Resource-Policy "same-origin"
Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'"
}
reverse_proxy localhost:3000
}Express (Helmet):
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'strict-dynamic'"],
objectSrc: ["'none'"],
baseUri: ["'self'"],
},
},
strictTransportSecurity: { maxAge: 31536000, includeSubDomains: true, preload: true },
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
crossOriginOpenerPolicy: { policy: 'same-origin' },
crossOriginResourcePolicy: { policy: 'same-origin' },
}));Helmet setzt die meisten Security-Header mit sicheren Defaults. Ergänzungen (CSP-Details, Permissions-Policy) gehören explizit konfiguriert.
Selbst-Test
Online-Scanner:
- securityheaders.com — Standard-Tool, Bewertung von A+ bis F. Gut für ersten Check.
- Mozilla Observatory — detaillierter, mit Empfehlungen.
- CSP Evaluator (Google) — speziell für CSP.
CLI:
# Headers ausgeben
curl -sI https://app.example.com | grep -iE 'strict-transport|content-security|x-content-type|referrer|permissions|cross-origin'
# nikto / nuclei für vollständige Scans
nuclei -t http/misconfiguration/http-missing-security-headers.yaml -u https://app.example.comIn CI:
Tools wie Nuclei oder eigene Scripts können als CI-Step laufen — Build failed wenn ein Header fehlt. Verhindert Regression bei Config-Änderungen.
Header-Konflikte und Edge-Cases
Multiple Headers: wenn sowohl Reverse-Proxy als auch App-Server denselben Header setzen, kann es zu Duplikaten kommen — abhängig vom Verhalten des Proxies entweder beide gesetzt (Browser nimmt unterschiedlich), oder einer überschrieben.
Pattern: entscheiden, wo Header gesetzt werden — entweder Reverse-Proxy (alle in nginx/Caddy) oder App-Server (Helmet), nicht beides. Bei vorhandenem CDN/Reverse-Proxy in der Chain ist es oft praktischer, Header dort zu setzen.
Conditional Headers: manche Header sollen pro Pfad anders sein (z. B. CSP für Admin-Panel strikter als für Public-Page). Pro-Location-Config in nginx oder Per-Route-Middleware in Express.
Header-Größe: Cookies plus Header haben in HTTP/1.1 ein Soft-Limit von ~8 KB. Zu viele/zu lange Header (CSP mit vielen Quellen) können Probleme machen. In HTTP/2 weniger relevant, aber gut, schlank zu bleiben.
Interessantes
Reporting-Endpoints für CSP, COEP, Permissions-Policy
Moderne Header unterstützen Report-Only-Modi und Reporting-Endpoints (report-to, report-uri). Damit kann man eine neue Policy ausrollen und beobachten, was Violations triggert, bevor man enforcement aktiviert. Vertieft in csp-deployment.
securityheaders.com gibt Grades aus, nicht Wahrheit
Ein A+ bei securityheaders.com bedeutet: alle empfohlenen Header sind gesetzt. Bedeutet NICHT: deine App ist sicher. Eine App mit perfektem Header-Score kann trotzdem SQL-Injection, IDOR, Logik-Bugs haben. Header sind eine Schicht, nicht die Sicherheit.
HTTP-Headers im Single-Page-App-Setup
Bei SPAs mit eigenem API-Backend müssen die Header auf der Backend-API (für API-Responses) plus auf dem CDN (für SPA-Hosting) gesetzt werden. Beide Stacks bedacht — sonst leakt entweder die API oder das HTML.
Server-Header verraten Tech-Stack
Server: nginx/1.24.0 oder X-Powered-By: Express sind Info für Angreifer — exakte Version macht CVE-Suche trivial. Patterns: Server-Header entfernen oder generisch (server_tokens off; in nginx, app.disable('x-powered-by') in Express). Defense-in-Depth, keine Hauptschutz-Schicht, aber kostenlos.
HTTP/3 ändert Header nicht — aber Setup-Stack
Moderne TLS-Stacks (Quiche, nginx 1.25+, Caddy) sprechen HTTP/3 (QUIC). Header bleiben gleich; nur Transport-Layer ändert sich. Wenn der Stack HTTP/3 spricht, automatisch über Alt-Svc-Header advertised. Browser fallbacks auf HTTP/2 wenn QUIC blockiert ist.
CDN-Cache und Vary-Header
Header, die pro User unterschiedlich sind (z. B. CSP mit nonce), brauchen einen Cache-Control: private. Sonst cached der CDN den Response mit der Nonce für andere User — XSS-Schutz bricht. Pattern: nonce-haltige Responses immer als private markieren, nicht CDN-cachebar.
Header-Stack-Diff zwischen Production und Staging
Production-Stack hat hardened Header, Staging meist nicht (für Debug-Zwecke). Risiko: Bugs zeigen sich erst in Prod. Pattern: Staging-Stack mit production-identischen Headers, plus separate Dev-Bypass via Header (X-Dev-Disable-CSP: true) oder Debug-Tool — strikt nur in Dev-Umgebung.
Weiterführende Ressourcen
Externe Quellen
- OWASP HTTP Headers Cheat Sheet
- MDN — HTTP Headers
- securityheaders.com
- Mozilla Observatory
- Google CSP Evaluator
- Helmet (Express Middleware)
- web.dev — Security Headers Quick Reference