Zurück zum Blog

Security-Header: HSTS, CSP, X-Frame-Options und andere

· 7 Min. Lesezeit

Das Backend ist die Festung, doch die zweite Verteidigungslinie liegt im Browser. HSTS, CSP und weitere Header blocken XSS, Clickjacking und MITM - kostenlos.

Security-Header: HSTS, CSP, X-Frame-Options und andere

Warum sie wichtig sind

Eine Anwendung kann auf dem Backend perfekt sicher und trotzdem anfällig für Angriffe auf der Browser-Seite sein: Cross-Site Scripting (XSS), Clickjacking, Protocol Downgrade, MIME Confusion. Security-Header verlagern die Verteidigung direkt in den Browser.

Strict-Transport-Security (HSTS)

Erzwingt HTTPS für alle künftigen Besuche. Nach dem ersten HTTPS-Besuch merkt sich der Browser die Domain und schreibt jeden http://-Link von selbst auf https:// um, selbst wenn der Benutzer auf einen schlechten Link klickt.

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
  • max-age=63072000 = gilt 2 Jahre
  • includeSubDomains = die Regel gilt auch für alle Subdomains; sie erzwingt HTTPS überall, sodass eine nur über HTTP laufende Subdomain, z. B. staging.example.com, im Browser unerreichbar wird
  • preload = ermöglicht die Aufnahme in die HSTS-Preload-Liste, die in Chrome / Firefox / Safari eingebaut ist

Achtung: Die Entfernung von HSTS mit preload aus der Liste dauert 6+ Monate. Fügen Sie preload erst hinzu, wenn Sie überprüft haben, dass HTTPS stabil auf allen Subdomains funktioniert.

Content-Security-Policy (CSP)

Der mächtigste, aber zugleich am schwierigsten zu konfigurierende Header. Er whitelistet, von wo der Browser Skripte, Styles, Bilder und iFrames laden darf. Ohne CSP kann ein Angreifer, der einen <script>-Tag injizieren kann, beliebiges JS ausführen; mit CSP nur Code aus genehmigten Quellen.

Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-...'; img-src 'self' data: https://cdn.example.com; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'

Übliche Direktiven:

  • default-src 'self' = standardmäßig nur Ressourcen aus meiner eigenen Domain erlauben
  • script-src = JS-Quellen (für Inline-Skripte einen Hash oder eine Nonce angeben)
  • style-src = CSS-Quellen
  • img-src = Bilder
  • connect-src = AJAX, WebSocket, EventSource
  • frame-ancestors 'none' = niemand darf die Seite in ein iFrame einbetten (besser als X-Frame-Options)
  • report-uri /csp-report = der Browser sendet bei jeder Verletzung ein JSON (Sie fangen es im Backend ab und loggen es)
  • Hinweis: report-uri ist heute deprecated - Browser mit report-to-Unterstützung ignorieren es. Der moderne Weg ist die report-to-Direktive plus ein separater Reporting-Endpoints-Header; behalten Sie report-uri nur als Fallback für Firefox, das report-to noch nicht unterstützt.

X-Frame-Options

Ältere Alternative zu frame-ancestors. Verhindert Clickjacking, bei dem ein Angreifer Ihre Seite als iFrame einbettet und sie mit unsichtbaren Buttons überlagert.

X-Frame-Options: DENY

Werte: DENY (niemand), SAMEORIGIN (nur meine Domain), ALLOW-FROM uri (deprecated).

X-Content-Type-Options

X-Content-Type-Options: nosniff

Schaltet MIME-Sniffing ab, sodass der Browser den Content-Type respektiert, den der Server zurückgegeben hat. Ohne das kann ein Angreifer eine Datei mit falschem Typ hochladen (z. B. ein Bild, das in Wahrheit HTML mit Skript ist) und der Browser kann es als Webseite ausführen.

Referrer-Policy

Referrer-Policy: strict-origin-when-cross-origin

Steuert, wie viele Informationen über die vorherige Seite der Browser beim Klick im Referer-Header sendet. Der Standardwert in modernen Browsern ist bereits strict-origin-when-cross-origin, doch das explizite Setzen des Headers garantiert ein konsistentes Verhalten.

Permissions-Policy

Schaltet APIs ab, die Sie nicht brauchen, etwa Kamera, Mikrofon, GPS und Geolocation. Ein Angreifer, der XSS ausnutzt, kann diese APIs nicht anfordern.

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

Praktische nginx-Konfiguration

server {
  listen 443 ssl http2;
  server_name example.com;

  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
  # preload haben wir hier bewusst weggelassen - füge es erst hinzu, wenn du dir 100% sicher bist (siehe preload-Falle oben)
  add_header X-Content-Type-Options "nosniff" always;
  add_header X-Frame-Options "DENY" always;
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
  add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

  # CSP ist umfangreich - definieren Sie sie nach Ihrer Anwendung
  add_header Content-Security-Policy "default-src 'self'; script-src 'self'; ..." always;
}

Entscheidend ist always - ohne das lässt nginx die Header bei Error-Responses (4xx, 5xx) weg.

Audit des aktuellen Stands

Am einfachsten über ein Online-Tool. Unser Header-Check zeigt Ihnen, welche Header fehlen und welche falsch sind. Für ein gründliches Audit gibt securityheaders.com zusätzlich eine A-F-Note.

Fazit

Security-Header gehören im Verhältnis von Aufwand zu Nutzen zu den besten Investitionen in die Sicherheit: typischerweise eine halbe Stunde Setup im Reverse Proxy gegen eine ganze Kategorie von Angriffen auf der Browser-Seite. Ein Audit einmal pro Halbjahr im Rahmen der regulären Wartung ist ein vernünftiges Minimum.

Kostenloses Security-Headers-Audit

Ohne Registrierung, Ergebnis in drei Sekunden.

Website testen →

Teilen: Link kopiert

ePulz.io kostenlos testen - 7 Tage, ohne Kreditkarte.

Konto erstellen