Kurz gesagt: Security Header sind Anweisungen des Webservers an den Browser, die Besucher vor Angriffen wie Cross-Site-Scripting, Clickjacking und unverschlüsselten Verbindungen schützen. Die wichtigsten sind HSTS, Content-Security-Policy, X-Content-Type-Options, Schutz gegen fremde Rahmen, Referrer-Policy und Permissions-Policy. Sie sind eine sinnvolle Härtung, ersetzen aber keine Updates auf dem Server.
Was Security Header leisten und was nicht
Bei jedem Seitenaufruf sendet der Webserver neben dem Inhalt auch Header mit. Einige davon steuern Sicherheitsfunktionen des Browsers. Damit lässt sich zum Beispiel festlegen, dass eine Seite nur über HTTPS geladen wird oder dass der Browser keine Skripte von fremden Domains ausführt.
Für Betreiber ist die Einordnung wichtig: Header schützen in erster Linie die Besucher, etwa vor dem Abgreifen von Sitzungen oder vor manipulierten Formularen. Sie schließen keine Lücken auf dem Server. Eine Schwachstelle in PHP, im CMS oder in einer Erweiterung bleibt bestehen, egal wie gut die Header gesetzt sind. Im Zusammenspiel mit sauberem Code begrenzen sie aber die Folgen vieler Fehler deutlich.
Die wichtigsten Security Header im Überblick
| Header | Zweck | Empfehlung als Ausgangspunkt |
|---|---|---|
| Strict-Transport-Security (HSTS) | erzwingt HTTPS für künftige Aufrufe | max-age=31536000; includeSubDomains |
| Content-Security-Policy (CSP) | legt erlaubte Quellen für Skripte, Bilder, Rahmen fest | individuell, zuerst als Report-Only |
| X-Content-Type-Options | verhindert, dass der Browser Dateitypen errät | nosniff |
| X-Frame-Options bzw. CSP frame-ancestors | verhindert Einbettung in fremde Seiten (Clickjacking) | SAMEORIGIN bzw. frame-ancestors 'self' |
| Referrer-Policy | begrenzt, welche Adresse an andere Seiten übermittelt wird | strict-origin-when-cross-origin |
| Permissions-Policy | schaltet Browserfunktionen wie Kamera oder Standort ab | nur benötigte Funktionen erlauben |
HSTS sollten Sie erst setzen, wenn alle Subdomains zuverlässig über HTTPS erreichbar sind. Der Browser merkt sich die Anweisung für die angegebene Zeit; ein Fehler lässt sich dann nicht sofort zurücknehmen. Beginnen Sie gegebenenfalls mit einer kurzen Laufzeit und erhöhen Sie sie nach erfolgreichen Tests. Die zusätzliche Option preload trägt die Domain dauerhaft in Listen der Browserhersteller ein und sollte nur nach sorgfältiger Prüfung gesetzt werden.
Header sind außerdem nicht die einzige Stelle, an der der Browser Schutz bietet. Cookies sollten die Attribute Secure, HttpOnly und SameSite tragen, damit Sitzungen nicht über unverschlüsselte Verbindungen oder Skripte abgegriffen werden. Wie Sie das in PHP einstellen, beschreibt der Ratgeber zu Sessions.
Security Header in Nginx setzen
In Nginx gehören die Header in den server-Block der jeweiligen Website. Der Zusatz always sorgt dafür, dass sie auch bei Fehlerseiten gesendet werden.
server {
# ...
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'" always;
server_tokens off;
}
Eine Eigenheit von Nginx: Setzt ein location-Block eigene add_header-Anweisungen, werden die Header aus dem server-Block dort nicht übernommen. Prüfen Sie deshalb auch Unterseiten und statische Dateien. Weitere Härtung für diese Kombination beschreibt Nginx mit PHP-FPM absichern.
Security Header in Apache setzen
Unter Apache benötigen Sie das Modul mod_headers. Die Anweisungen gehören in den VirtualHost oder, wenn kein Zugriff darauf besteht, in die .htaccess.
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
</IfModule>
ServerTokens Prod
ServerSignature Off
ServerTokens und ServerSignature gehören in die Hauptkonfiguration. Sie verhindern, dass der Server seine genaue Version in Antworten und Fehlerseiten nennt. In der php.ini erreichen Sie dasselbe für PHP mit expose_php = Off.
Content-Security-Policy schrittweise einführen
Die Content-Security-Policy ist der wirksamste, aber auch anspruchsvollste Header. Sie legt fest, aus welchen Quellen Skripte, Stylesheets, Bilder, Schriften und Rahmen geladen werden dürfen. Wird ein eingeschleustes Skript von einer fremden Domain nachgeladen, blockiert der Browser es.
Moderne Websites binden oft Analyse-Werkzeuge, Zahlungsanbieter, Kartendienste oder Videos ein. Eine zu strenge Richtlinie legt dann Funktionen lahm. Gehen Sie deshalb in Stufen vor:
- Zuerst mit
Content-Security-Policy-Report-Onlystarten. Der Browser meldet Verstöße in der Entwicklerkonsole oder an eine Sammeladresse, blockiert aber nichts. - Alle benötigten Quellen erfassen und gezielt freigeben, statt pauschale Platzhalter zu verwenden.
- Inline-Skripte schrittweise in Dateien auslagern oder mit Nonces versehen, damit auf
'unsafe-inline'verzichtet werden kann. - Erst nach einer Testphase ohne unerwartete Meldungen auf
Content-Security-Policyumstellen.
Die CSP ergänzt sauberes Escaping im Code, ersetzt es aber nicht. Wie Sie Ausgaben in PHP richtig absichern, steht im Ratgeber Cross-Site-Scripting in PHP verhindern.
Header prüfen und typische Fehler vermeiden
Nach jeder Änderung sollten Sie prüfen, ob die Header tatsächlich ankommen. Das geht ohne zusätzliche Werkzeuge mit curl:
# Konfiguration testen und neu laden
nginx -t && systemctl reload nginx
# Header der Startseite und einer statischen Datei anzeigen
curl -sI https://www.example.de/ | grep -iE 'strict|content-security|x-content|x-frame|referrer|permissions|server'
curl -sI https://www.example.de/favicon.ico | grep -iE 'strict|x-content'
Typische Fehler sind doppelt gesetzte Header, wenn Webserver und Anwendung dieselben Header senden, ein vorgeschaltetes CDN, das Header entfernt oder überschreibt, und Header, die nur auf der Startseite, aber nicht bei Weiterleitungen oder Fehlerseiten erscheinen. Prüfen Sie außerdem nach Updates des CMS oder von Sicherheits-Erweiterungen, ob sich die Header verändert haben.
Legen Sie deshalb eine Stelle fest, an der die Header gepflegt werden, am besten den Webserver oder den vorgeschalteten Dienst. Viele CMS-Erweiterungen bieten ebenfalls Einstellungen für Sicherheits-Header. Das ist bequem, führt aber leicht zu doppelten oder widersprüchlichen Angaben, wenn zusätzlich der Server Header setzt. Für einzelne Tests eignen sich auch die Entwicklerwerkzeuge des Browsers: Im Netzwerk-Reiter sehen Sie zu jeder Anfrage die Antwort-Header, und die Konsole zeigt Verstöße gegen die Content-Security-Policy an.
Wie hilft PHP SOS konkret?
- Wir prüfen die aktuellen Header aller Ihrer Websites, auch hinter CDN und Proxy, und zeigen Lücken und Widersprüche auf.
- Wir setzen die Header zentral im Webserver im Rahmen der Server-Härtung und testen Startseite, Unterseiten und Fehlerseiten.
- Wir führen die Content-Security-Policy im Report-Only-Modus ein, werten die Meldungen aus und schalten sie nach Abstimmung scharf.
- Wo Code-Änderungen nicht sofort möglich sind, ergänzen wir den Schutz durch WAF-Regeln und virtuelles Patching.
Häufige Fragen
Was sind Security Header?
Security Header sind Zusatzangaben in der Antwort des Webservers. Sie sagen dem Browser zum Beispiel, dass er die Seite nur über HTTPS laden, keine fremden Skripte ausführen oder die Seite nicht in fremden Rahmen anzeigen soll. Sie schützen vor allem die Besucher.
Schützen Security Header vor PHP2Shell?
Nein. PHP2Shell ist eine Lücke in PHP auf dem Server, Header wirken im Browser des Besuchers. Gegen PHP2Shell hilft das Update auf eine behobene PHP-Version und der Neustart aller Worker. Header sind eine ergänzende Härtung für andere Angriffsarten.
Kann eine Content-Security-Policy meine Website kaputtmachen?
Ja, eine zu strenge Richtlinie blockiert benötigte Skripte, Schriften oder eingebettete Inhalte. Deshalb führt man sie zuerst im Report-Only-Modus ein, wertet die Meldungen aus und schaltet erst dann auf Durchsetzung um.
Ist X-XSS-Protection noch sinnvoll?
Nein. Aktuelle Browser werten diesen Header nicht mehr aus, und die Empfehlung lautet, ihn wegzulassen oder auf 0 zu setzen. Schutz vor Cross-Site-Scripting bieten sauberes Escaping im Code und eine Content-Security-Policy.