Server-Rezept
Sie können jeden Header, den WordPress braucht, mit einer Handvoll Zeilen und ohne Plugin setzen. Schwieriger ist, sie so abzulegen, dass ein Theme-Update sie nicht entfernt, und zu wissen, welcher davon Ihren Adminbereich zerlegt.
01 Wohin es gehört
Die Aktion send_headers wird ausgelöst, bevor WordPress eine Antwort sendet, und ist damit der richtige Haken. Der übliche Rat lautet, den Code in die functions.php des Themes zu legen, und genau dort geht es schief: ein Theme-Wechsel entfernt Ihre Security-Header, und ein Update eines Themes, das kein Child-Theme ist, überschreibt die Datei komplett.
Legen Sie es stattdessen in ein kleines eigenes Plugin, eine einzelne PHP-Datei unter wp-content/plugins, die Sie einmal aktivieren. Es übersteht Theme-Wechsel und Updates, es lässt sich mit einem Klick abschalten, wenn ein Header etwas kaputt macht, und es hält Konfiguration aus der Darstellung heraus. Haben Sie Zugriff auf den Webserver, sind die Header dort noch besser aufgehoben, weil sie dann auch statische Dateien abdecken, die PHP nie erreichen.
02 Das Rezept
Ein sicherer Ausgangspunkt. Die is_admin-Abfrage zählt: eine strenge Content-Security-Policy zerlegt den Block-Editor und den Customizer, die auf Inline-Skripte angewiesen sind, deshalb gilt die Richtlinie nur für die öffentliche Seite.
add_action( 'send_headers', function () { if ( is_admin() ) { return; } header( 'Strict-Transport-Security: max-age=63072000; includeSubDomains' );
header( "Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'" );
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'X-Content-Type-Options: nosniff' );
header( 'Referrer-Policy: strict-origin-when-cross-origin' );
header( 'Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=()' ); } ); Die Content-Security-Policy oben erlaubt nichts von Dritten und blockiert eingebettete Karten, Schriften, Analyse und die meisten Page-Builder. Auf einer echten WordPress-Seite beginnen Sie mit Content-Security-Policy-Report-Only, sammeln, was sie blockiert hätte, und weiten die Richtlinie von dort aus.
03 Zeile für Zeile
Jeder Header 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 nur über HTTPS zu erreichen. Setzen Sie das nach Möglichkeit am Webserver statt in PHP, damit es auch Anfragen abdeckt, die WordPress nie erreichen.
header( 'Strict-Transport-Security: max-age=63072000; includeSubDomains' ); Content-Security-Policy Was sie macht. Fangen Sie hier an und nicht beim erzwingenden Header. Report-Only ändert für Besucher nichts, sagt Ihnen aber, was eine strenge Richtlinie blockiert hätte, und das ist auf einer WordPress-Seite mit Plugins meist mehr als erwartet.
header( "Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'" );
header( "Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; report-uri /csp-report" ); X-Frame-Options Was sie macht. SAMEORIGIN statt DENY, weil Teile von WordPress ihre eigenen Seiten einbetten: der Customizer zeigt die Seite in einem iframe, und DENY macht das kaputt.
header( 'X-Frame-Options: SAMEORIGIN' ); X-Content-Type-Options Was sie macht. Sagt dem Browser, Ihren angegebenen Inhaltstypen zu vertrauen. Auf jeder Seite unbedenklich, auch auf einer mit Medien-Uploads, wo es eine ganze Angriffsklasse über hochgeladene Dateien entfernt.
header( 'X-Content-Type-Options: nosniff' ); Referrer-Policy Was sie macht. Sendet die vollständige Adresse innerhalb Ihrer eigenen Seite und nach außen nur die bloße Domain. Der richtige Wert für nahezu jede öffentliche WordPress-Seite.
header( 'Referrer-Policy: strict-origin-when-cross-origin' ); Permissions-Policy Was sie macht. Schaltet Kamera, Mikrofon, Standort, Bezahlfunktion und USB-Zugriff für Ihre Seiten und alles darin Eingebettete ab. Erweitern Sie die Liste, statt sie zu kürzen: eine Funktion, die Sie nicht nennen, bleibt verfügbar, auch für alles, was ein Plugin einbettet.
header( 'Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=()' ); Set-Cookie Was sie macht. WordPress setzt seine eigenen Anmelde-Cookies mit den richtigen Attributen, PHP-Session-Cookies aus Plugins haben sie aber oft nicht. Diese drei Zeilen korrigieren die Voreinstellungen für alles, was auf der Seite läuft.
ini_set( 'session.cookie_secure', '1' );
ini_set( 'session.cookie_httponly', '1' );
ini_set( 'session.cookie_samesite', 'Lax' ); 04 Nachprüfen
Ein Caching-Plugin oder ein CDN sitzt zwischen PHP und Ihrem Besucher und liefert womöglich eine zwischengespeicherte Fassung aus, die entstand, bevor es Ihre Header gab. Ein aktiviertes Plugin beweist also für sich genommen nichts.
curl -sI https://example.com | grep -i "^strict-transport\|^content-security\|^x-frame" Leeren Sie zuerst jede Cache-Ebene, dann rufen Sie die Seite ab. Prüfen Sie auch die Anmeldeseite: bleibt sie leer, erreicht die Content-Security-Policy Seiten, die die is_admin-Abfrage nicht abdeckt.
05 Fragen
Ein Plugin ist eine vernünftige Wahl, wenn Ihnen eine Einstellungsseite lieber ist als eine Datei, und die großen Sicherheits-Plugins machen das korrekt. Sie kaufen damit Bequemlichkeit, keine besseren Header: die Werte sind dieselben, und Sie handeln sich ein weiteres Plugin ein, das aktuell gehalten werden will.
Weil es in dem Moment verschwindet, in dem das Theme wechselt, und beim nächsten Update verloren ist, sofern Sie kein Child-Theme benutzen. Sicherheitskonfiguration sollte nicht daran hängen, wie Ihre Seite aussieht.
Plugin abschalten und die Richtlinie als Content-Security-Policy-Report-Only wieder einführen. WordPress-Seiten laden Skripte und Stile aus Plugins, aus Page-Buildern und oft von externen Diensten, und eine Richtlinie, die nur den eigenen Ursprung erlaubt, blockiert davon einiges.
Ja, genau diesen Fall deckt der Weg über PHP ab. Was Ihnen fehlt, ist die Abdeckung von Dateien, die PHP nie erreichen, also Bilder und Stylesheets, die der Webserver direkt ausliefert. Für die meisten Seiten zählen die Seiten selbst, und manche Managed-Hoster lassen Header auch in ihrer Oberfläche setzen.
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 Plugin-Liste, und erklärt jeden Befund verständlich.