Server-Rezept
Ein vollständiger Server-Block zum Einfügen, eine Erklärung Zeile für Zeile zu dem, was Sie gerade eingefügt haben, und das eine nginx-Verhalten, das alles davon still aushebelt.
01 Wohin es gehört
Die Direktiven gehören in den Server-Block, der Ihre Seite ausliefert, neben Ihre TLS-Konfiguration. Sie gelten dann für jede Antwort dieses virtuellen Hosts, auch für statische Dateien und Fehlerseiten, und genau das wollen Sie: ein Security-Header, der auf Ihrer 404-Seite fehlt, fehlt auf einer Seite, die Angreifer erreichen können.
Die Falle ist die Vererbung. nginx erbt add_header-Direktiven aus einem äusseren Block nur so lange, wie der innere Block keine eigenen definiert. Ein einziges add_header innerhalb einer Location, und sämtliche Header aus dem Server-Block gelten dort nicht mehr, ohne Warnung und ohne Fehler im Konfigurationstest. Brauchen Sie in einer Location einen Header, wiederholen Sie dort alle.
02 Das Rezept
Ein sicherer Ausgangspunkt für eine Seite, die ihre eigenen Dateien ausliefert. Das always zählt: ohne es setzt nginx den Header nur bei einer Handvoll erfolgreicher Statuscodes und lässt Ihre Weiterleitungen und Fehlerantworten blank.
server { listen 443 ssl; server_name example.com; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=()" always; } Zwei Anpassungen, bevor das Ihres ist. Die Content-Security-Policy oben erlaubt nichts von Dritten, bindet Ihre Seite also Karten, Schriften oder Analyse ein, blockiert sie diese, und Sie sollten sie zuerst über Content-Security-Policy-Report-Only ausrollen. Und lassen Sie preload aus dem HSTS-Header, bis Sie gelesen haben, worauf es Sie festlegt.
03 Zeile für Zeile
Jede Direktive aus dem Block oben einzeln, damit Sie weglassen können, was nicht zu Ihrer Seite passt, statt etwas einzufügen, das Sie nicht erklären können.
Strict-Transport-Security Was sie macht. Legt Browser darauf fest, Ihre Seite zwei Jahre lang nur über HTTPS zu erreichen. Fügen Sie das erst hinzu, wenn HTTPS auf der ganzen Domain funktioniert, auch auf jeder Subdomain, denn includeSubDomains gilt auch für Hosts, die Sie vergessen haben.
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; Content-Security-Policy Was sie macht. Beschränkt jede Ressource auf Ihren eigenen Ursprung und verbietet das Einbetten vollständig. Das ist die Zeile, die auf einer echten Seite am ehesten etwas kaputt macht, und die einzige, die Sie zuerst im Report-Only-Modus ausrollen sollten.
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; report-uri /csp-report" always; X-Frame-Options Was sie macht. Verhindert, dass Ihre Seiten irgendwo in einem Rahmen eingebettet werden. Nehmen Sie stattdessen SAMEORIGIN, wenn ein Teil Ihrer eigenen Seite einen anderen einbettet.
add_header X-Frame-Options "DENY" always; X-Content-Type-Options Was sie macht. Sagt dem Browser, Ihren angegebenen Inhaltstypen zu vertrauen, statt zu raten. Es gibt keine Seite, auf der dieser Wert falsch wäre; einfügen und weitergehen.
add_header X-Content-Type-Options "nosniff" always; Referrer-Policy Was sie macht. Sendet die vollständige Adresse innerhalb Ihrer eigenen Seite und nach außen nur die bloße Domain. Das ist der Wert für nahezu jede öffentliche Website.
add_header Referrer-Policy "strict-origin-when-cross-origin" always; Permissions-Policy Was sie macht. Schaltet Kamera, Mikrofon, Standort, Bezahlfunktion und USB-Zugriff für Ihre Seiten und alles Eingebettete ab. Erweitern Sie die Liste, statt sie zu kürzen: Funktionen, die Sie nicht nennen, bleiben verfügbar.
add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=()" always; 04 Nachprüfen
nginx -t fängt einen Syntaxfehler, sagt aber nichts darüber, ob ein Header tatsächlich bei einem Browser ankommt, und die Vererbungsfalle oben erzeugt eine Konfiguration, die sauber testet und nichts ausliefert. Neu laden, dann eine echte Antwort ansehen.
nginx -t && systemctl reload nginx curl -sI https://example.com | grep -i "^strict-transport\|^content-security\|^x-frame" Prüfen Sie eine Adresse innerhalb eines Location-Blocks und nicht nur die Startseite, und prüfen Sie eine 404. Das sind die beiden Stellen, an denen Header verschwinden, ohne dass etwas falsch aussieht.
05 Fragen
Fast immer die Vererbungsregel: irgendein Location-Block weiter hinten definiert ein eigenes add_header und verwirft damit jedes geerbte. Suchen Sie Ihre Konfiguration nach add_header ab und wiederholen Sie den vollständigen Satz in jedem Block, der eines hat.
Ohne always setzt nginx den Header nur bei einer kurzen Liste erfolgreicher Antworten. Weiterleitungen, 404er und 5xx-Seiten gehen ohne ihn raus, und genau diese Antworten sieht sich ein Angreifer am ehesten an.
Sie können, und bei mehreren Seiten auf einem Server ist es verlockend. Dieselbe Vererbungsregel gilt auf jeder Ebene weiter, ein einzelnes add_header in einem Server-Block entfernt also den ganzen Satz für diese Seite. Je Server-Block zu setzen ist mühsamer und deutlich schwerer versehentlich kaputtzumachen.
Es kann eigene hinzufügen, und dann stehen zwei Werte für denselben Header in der Antwort, was Browser uneinheitlich behandeln. Sendet Ihre Anwendung ebenfalls Security-Header, entscheiden Sie sich für eine Ebene und schalten Sie die andere ab, statt beide laufen zu lassen.
06 Im Detail
Diese Seite ist die Konfiguration. Diese Ratgeber erklären, was jeder Header wirklich macht und wie Sie seinen Wert wählen.
Was jeder Response-Header bewirkt, welche Ihre Website senden sollte und wie Sie sie richtig konfigurieren.
Der stärkste Schutz gegen Cross-Site-Scripting: welche Direktiven Sie setzen, wie Sie eine Richtlinie im Report-Only-Modus einführen und wie Sie erzwingend werden, ohne Ihre Website zu zerlegen.
Strict-Transport-Security erklärt: was max-age, includeSubDomains und preload wirklich bewirken und warum die Preload-Liste eine Entscheidung ist, die Sie nicht schnell zurücknehmen können.
Secure, HttpOnly und SameSite: die Cookie-Attribute, die eine Sitzung vor Skripten und fremden Seiten schützen, samt Einstellungen für einen typischen Stack.
Wie eine unsichtbare Überlagerung aus einem Besucherklick eine Aktion auf Ihrer Website macht, und die zwei Header, die das verhindern: X-Frame-Options für ältere Clients, frame-ancestors für alles andere.
Welcher Teil Ihrer URLs an fremde Seiten geht, wenn ein Besucher weiterklickt: die fünf Werte, die zählen, was jeder davon preisgibt und welcher der sinnvolle Standard ist.
Kamera, Mikrofon, Standort und Bezahlfunktion für Ihre Website und alle eingebetteten Inhalte abschalten: die Syntax der Positivliste und warum eine nicht genannte Funktion keine abgeschaltete Funktion ist.
Die Einträge, die verhindern, dass jemand in Ihrem Namen Mails verschickt, und der, der Ihre DNS-Antworten ehrlich hält: was jeder leistet und in welcher Reihenfolge Sie sie einführen.
Die Datei, die Sicherheitsforschern sagt, wohin eine Schwachstelle gemeldet wird. Zwei Pflichtfelder, zehn Minuten Arbeit, und der Unterschied zwischen einer privaten und einer öffentlichen Meldung.
Ein Header, der heute stimmt, kann nach dem nächsten Deploy fehlen. Drei Wege, das zu bemerken: ein Cronjob mit curl, eine Prüfung in Ihrer CI-Pipeline und ein geplanter Scan, jeweils mit dem, was er findet und was nicht.
Wie sich eine Richtlinie durch Deploys, Plugins und CDN-Regeln unbemerkt ändert und wie Sie es merken: ein Header-Diff, Verstoßmeldungen über report-to und was ein Scan-Vergleich zeigen kann und was nicht.
Weiterlesen
Jeder Ratgeber steht für sich, zusammen decken sie ab, worauf unser Scanner schaut. Wählen Sie den, der Ihrer nächsten Frage am nächsten kommt.
Unser kostenloser Quickscan liest die Header aus Ihrer ausgelieferten Antwort und nicht aus Ihrer Konfigurationsdatei, und erklärt jeden Befund verständlich.