HTTP-Sicherheitsheader sind Anweisungen, die der Server mit jeder Antwort mitsendet, damit der Browser zusätzliche Schutzmaßnahmen anwendet: HTTPS erzwingen (Strict-Transport-Security), begrenzen, woher Skripte und andere Ressourcen geladen werden dürfen (Content-Security-Policy), verhindern, dass die Website in andere Seiten eingebettet wird (X-Frame-Options / frame-ancestors), den Browser daran hindern, Dateitypen zu „erraten“ (X-Content-Type-Options), steuern, welche Referrer-Informationen an andere Websites gesendet werden (Referrer-Policy), und Browser-APIs abschalten, die du nicht nutzt (Permissions-Policy). Sie werden auf dem Server oder beim Hosting-Anbieter konfiguriert, nicht im HTML, und eine statische Website kann alle in wenigen Minuten haben.
Dieser Artikel erklärt, was jeder bewirkt, welchen Wert du auf einer typischen Website verwendest und wie du prüfst, dass sie aktiv sind.
Warum sie auf einer Website „ohne etwas zu stehlen“ wichtig sind
Ein Blog ohne registrierte Nutzer wirkt wie ein unattraktives Ziel, aber die Header schützen deine Besucher: Sie verhindern, dass ein kompromittiertes Drittanbieter-Skript Code einschleust, dass jemand deine Website in einen Frame einbettet, um Klicks zu erschleichen (Clickjacking), oder dass eine auf HTTP herabgestufte Verbindung Inhaltsmanipulation erlaubt. Sie kosten zudem keine Performance und signalisieren eine sorgfältig gepflegte Website.
Die sechs Header und ihre empfohlenen Werte
1. Strict-Transport-Security (HSTS)
Sagt dem Browser, dass er sich für den angegebenen Zeitraum nur über HTTPS mit deiner Domain verbinden soll, selbst wenn der Nutzer http:// eingibt oder einem alten Link folgt.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age=31536000: ein Jahr, in Sekunden.includeSubDomains: gilt auch für Subdomains. Stelle sicher, dass alle HTTPS ausliefern, bevor du es aktivierst.preload: erlaubt die Aufnahme der Domain in die in Browsern eingebaute Preload-Liste, sodass selbst der erste Besuch nie HTTP verwendet. Fügepreloadnur hinzu, wenn du die Domain wirklich bei der Liste einreichst; es ist schwer rückgängig zu machen.
Beginne mit einem kurzen max-age (zum Beispiel 300), um zu prüfen, dass nichts bricht, und erhöhe ihn danach.
2. Content-Security-Policy (CSP)
Der mächtigste und heikelste: Er definiert, von welchen Origins der Browser Skripte, Styles, Bilder, Schriften, Verbindungen und iframes laden darf. Ein von einem nicht autorisierten Origin eingeschleustes Skript wird schlicht nicht ausgeführt.
Ein Ausgangspunkt für eine statische Website ohne Drittanbieter:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests
Praktische Hinweise:
'self'ist dein eigener Origin. Jeder externe Dienst (Analytics, Werbung, Schriften, Videos) muss explizit zur passenden Direktive hinzugefügt werden.- Vermeide
'unsafe-inline'inscript-src: Es hebt einen Großteil des Schutzes auf. Brauchst du Inline-Skripte, nutze Nonces oder Hashes. Instyle-srcwird es öfter toleriert, weil viele Code-Highlighter und Komponenten Inline-Styles erzeugen, obwohl es ideal wäre, es auch dort zu entfernen. frame-ancestors 'none'ersetztX-Frame-Optionsin modernen Browsern.- Teste zuerst mit
Content-Security-Policy-Report-Only, das Verstöße meldet, ohne etwas zu blockieren, und beobachte die Browser-Konsole.
3. X-Content-Type-Options
X-Content-Type-Options: nosniff
Verhindert, dass der Browser eine Datei als einen anderen Typ interpretiert als im Content-Type deklariert (zum Beispiel etwas als Skript ausführt, das als Text ausgeliefert wurde). Immer, ohne Ausnahmen.
4. X-Frame-Options
X-Frame-Options: DENY
Verbietet, dass deine Seite im <iframe> einer anderen Website geladen wird (Schutz vor Clickjacking). SAMEORIGIN erlaubt das Einbetten nur von deiner eigenen Domain. Heute deckt frame-ancestors aus der CSP dasselbe präziser ab; behalte beide für ältere Browser.
5. Referrer-Policy
Referrer-Policy: strict-origin-when-cross-origin
Steuert, wie viel von der Ursprungs-URL im Header Referer gesendet wird, wenn zu einer anderen Website navigiert wird. Mit diesem Wert erhalten andere Domains nur den Origin (https://blog.aimran.es) und nie den vollständigen Pfad, und beim Wechsel von HTTPS zu HTTP gar nichts. Es ist der Standard in modernen Browsern, aber ihn zu deklarieren vermeidet, davon abhängig zu sein.
6. Permissions-Policy
Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
Schaltet Browser-APIs ab, die deine Website nicht nutzt, auch für jedes eingebettete Drittanbieter-iframe. Die Liste der verfügbaren Funktionen steht auf MDN; deklariere die, die du nicht brauchst, als leer (()).
Übersichtstabelle
| Header | Schützt vor | Empfohlener Wert |
|---|---|---|
Strict-Transport-Security |
HTTP-Verbindungen, Protokoll-Downgrade | max-age=31536000; includeSubDomains (+ preload, wenn du sie registrierst) |
Content-Security-Policy |
Skript-Injektion (XSS), nicht autorisierte Ressourcen | Mit default-src 'self' beginnen und benötigte Origins ergänzen |
X-Content-Type-Options |
Fehlinterpretierte Dateitypen | nosniff |
X-Frame-Options |
Clickjacking (ältere Browser) | DENY |
Referrer-Policy |
Weitergabe interner URLs an Dritte | strict-origin-when-cross-origin |
Permissions-Policy |
Nutzung sensibler APIs durch deine Website oder iframes | Abschalten, was du nicht nutzt |
Wo du sie konfigurierst
- Netlify und Cloudflare Pages: eine Datei
_headersim veröffentlichten Ordner. - Vercel: der Schlüssel
headersinvercel.json. - Nginx:
add_header-Direktiven imserver-Block. - Apache:
Header set-Direktiven in der Konfiguration oder.htaccess. - WordPress: über den Server (bevorzugt) oder ein Sicherheits-Plugin, das sie hinzufügt.
Die Empfehlung ist, sie in einer einzigen versionierten Datei neben dem Code zu halten, damit eine Änderung an der Website (zum Beispiel das Aktivieren von Werbung) bedeutet, die CSP im selben Commit zu überprüfen.
Wie du sie prüfst
curl -sI https://blog.aimran.es/de/ | grep -iE "strict-transport|content-security|x-content-type|x-frame|referrer-policy|permissions-policy"
Online-Werkzeuge wie securityheaders.com oder Mozillas HTTP Observatory analysieren die Antwort und bewerten die Konfiguration. Und die Browser-Konsole zeigt jeden CSP-Verstoß mit der blockierten Ressource, was das Feinjustieren der Richtlinie erleichtert.
Häufige Fehler
- HSTS mit
preloadaktivieren, bevor jede Subdomain auf HTTPS läuft: Sie funktionieren nicht mehr, und das Zurücknehmen dauert Monate. - Eine CSP mit
'unsafe-inline'und'unsafe-eval'in Skripten, „damit alles funktioniert“: Sie hakt das Kästchen ab und schützt wenig. - Die CSP vergessen, wenn ein Drittanbieter hinzukommt (Werbung, Analytics, ein Widget): Die Ressource wird stillschweigend blockiert und es wirkt, als „lade sie nicht“.
- Die Header nur auf der Startseite setzen und nicht auf den anderen Routen oder statischen Dateien.
- Nicht im Report-Only-Modus testen, bevor blockiert wird.
Fazit
Sechs Header, eine Konfigurationsdatei und ein paar Minuten: HSTS, um HTTPS zu erzwingen, CSP, um zu kontrollieren, was geladen wird, nosniff und X-Frame-Options/frame-ancestors, um klassische Vektoren zu schließen, Referrer-Policy, um keine URLs preiszugeben, und Permissions-Policy, um abzuschalten, was du nicht nutzt. Setze die CSP zuerst im Report-Only-Modus ein, prüfe die Konsole und versioniere die Header mit dem Code, damit sie sich mit der Website weiterentwickeln.