image² Web Security Headers

Status: Aktiv im Einsatz

Typ: Custom Plugin (Agenturstandard)

Version: 2.x

Zweck: Serverseitiges Setzen stabiler Security-Header über WordPress/PHP

Kompatibilität: Serverunabhängig, für Apache/nginx/Plesk/Mittwald etc. geeignet

Ziel des Plugins

Das Plugin setzt grundlegende sicherheitsrelevante HTTP-Header direkt über WordPress.

Die Header werden über den WordPress-Hook send_headers ausgegeben und sind damit nicht von der Serverkonfiguration oder einer beschreibbaren .htaccess abhängig.

Die Umstellung auf diese Variante erfolgte, weil die frühere .htaccess-Version nicht auf allen Hosting-Umgebungen zuverlässig funktionierte.

Es handelt sich bewusst um eine minimale, stabile Agenturversion ohne zusätzliche Konfiguration oder projektabhängige Regeln.

Gesetzte Header

  • Strict-Transport-Security: max-age=31536000
    Erzwingt bei HTTPS-Verbindungen für 12 Monate den weiteren Zugriff über HTTPS.
  • X-Content-Type-Options: nosniff
    Verhindert MIME-Type-Sniffing durch den Browser.
  • X-Frame-Options: SAMEORIGIN
    Verhindert das Einbetten der Website in Frames fremder Domains und bietet damit grundlegenden Schutz vor Clickjacking.
  • Referrer-Policy: strict-origin-when-cross-origin
    Begrenzt die Weitergabe von Referrer-Informationen bei externen Aufrufen.
  • Permissions-Policy
    Deaktiviert Browser-Funktionen, die unsere Standard-Websites nicht brauchen:

    • Accelerometer
    • Kamera
    • Geolocation
    • Gyroscope
    • Magnetometer
    • Mikrofon
    • Payment API
    • USB

Strict-Transport-Security wird nur ausgegeben, wenn WordPress die Verbindung als HTTPS erkennt.

Warum kein X-XSS-Protection mehr?

Die frühere Plugin-Version setzte zusätzlich:

X-XSS-Protection: 1; mode=block

Dieser Header ist veraltet und wird von modernen Browsern nicht mehr als zeitgemäßer XSS-Schutz verwendet.

Er wurde deshalb mit Version 2 entfernt.

Warum keine Content Security Policy (CSP)?

Die CSP wurde bewusst nicht integriert.

Technischer Hintergrund

Eine Content Security Policy ist:

  • hochgradig projektabhängig
  • stark von externen Ressourcen abhängig
  • empfindlich gegenüber Drittanbieter-Skripten
  • konfliktanfällig bei Tracking-Tools, Maps, Fonts, APIs und eingebetteten Inhalten

In einer Agenturumgebung mit beispielsweise:

  • Elementor
  • Crocoblock
  • externen APIs
  • Marketing-Integrationen
  • Cookie-Tools
  • unterschiedlichen Drittanbieter-Diensten

würde eine generische CSP:

  • entweder ständig angepasst werden müssen
  • regelmäßig Funktionen blockieren
  • oder so großzügig formuliert werden, dass ihr Sicherheitsnutzen gering ist

Eine universelle CSP ist deshalb für dynamische Kundenprojekte nicht sinnvoll.

Sicherheitsphilosophie

Dieses Plugin verfolgt eine klare Linie:

  • stabile, universell einsetzbare Header setzen
  • unterschiedliche Hosting-Umgebungen unterstützen
  • keine projektindividuellen Policies erzwingen
  • keine unnötige Wartungsabhängigkeit erzeugen
  • keine Funktionen von WordPress oder Drittanbieter-Plugins unnötig blockieren

Eine CSP wird nur eingesetzt, wenn:

  • ein Projekt sie explizit erfordert
  • die verwendeten Ressourcen klar definiert sind
  • externe Dienste vollständig erfasst werden können
  • ein dediziertes CSP-Testing erfolgt

Technische Funktionsweise

Das Plugin verwendet den WordPress-Hook:

send_headers

Die Security-Header werden damit per PHP ausgegeben, bevor WordPress die eigentliche Response an den Browser sendet.

Das Plugin:

  • verändert keine .htaccess
  • braucht kein Apache mod_headers
  • braucht keine nginx-Konfiguration
  • braucht keine Schreibrechte auf Server-Konfigurationsdateien
  • braucht kein JavaScript
  • braucht keine Frontend-Oberfläche
  • braucht keine Einstellungen

Dadurch funktioniert dieselbe Plugin-Version auf unterschiedlichen Hosting-Umgebungen wesentlich zuverlässiger.

Migration von Version 1.x

Version 1.x setzte die Security-Header über einen eigenen Block in der .htaccess:

# BEGIN image2 Security Headers

Beim Wechsel auf Version 2 prüft das Plugin einmalig, ob dieser alte Block vorhanden ist, und entfernt ihn, sofern die .htaccess beschreibbar ist.

Damit werden doppelt gesetzte Header nach einem Update vermieden.

Anschließend verändert Version 2 die .htaccess nicht mehr.

Unterschied zur alten .htaccess-Version

Die alte Version setzte die Header auf Webserver-Ebene. Dadurch konnten die Header auch bei direkt vom Webserver ausgelieferten statischen Dateien greifen.

Version 2 setzt die Header auf Responses, die über WordPress/PHP ausgeliefert werden.

Dieser Unterschied ist bewusst in Kauf genommen worden, da die .htaccess-Variante von der jeweiligen Serverarchitektur abhängig war und beispielsweise auf bestimmten Hosting-Umgebungen nicht zuverlässig funktionierte.

Für den normalen WordPress-Aufruf werden die relevanten Security-Header mit Version 2 zuverlässig gesetzt.

Vorteile der aktuellen Lösung

  • serverunabhängiger als die alte .htaccess-Variante
  • funktioniert auch in Hosting-Umgebungen ohne nutzbare .htaccess
  • keine Abhängigkeit von mod_headers
  • keine Schreibrechte auf .htaccess erforderlich
  • keine Theme-Abhängigkeit
  • kein zusätzliches JavaScript
  • keine Einstellungen notwendig
  • sehr geringer Laufzeitaufwand
  • einheitlicher Agenturstandard für unterschiedliche Hoster

Einschränkungen

  • Header werden nur auf Responses gesetzt, die über WordPress/PHP laufen
  • direkt vom Webserver ausgelieferte statische Dateien erhalten durch das Plugin keine zusätzlichen Header
  • kein CSP-Schutz enthalten
  • keine WAF-Funktion
  • ersetzt keine serverseitigen Sicherheitsmaßnahmen
  • HSTS setzt eine korrekt konfigurierte HTTPS-Website voraus

Kontrolle nach Installation

Nach Installation oder Update können die Response Header im Browser über die Entwicklertools geprüft werden.

Unter Netzwerk → Dokument → Response Headers sollten unter anderem folgende Header sichtbar sein:

strict-transport-security: max-age=31536000

x-content-type-options: nosniff

x-frame-options: SAMEORIGIN

referrer-policy: strict-origin-when-cross-origin

permissions-policy: ...

x-xss-protection gehört dagegen nicht mehr zu unserem Standard und muss nicht vorhanden sein.

Caching-Hinweis

Die Header werden über WordPress/PHP gesetzt.

Wenn ein Server, Reverse Proxy oder Full-Page-Cache eine Seite vollständig ausliefert, ohne WordPress auszuführen, kann das Plugin bei dieser konkreten Response keine zusätzlichen Header ergänzen.

Das ist ein technischer Unterschied zur früheren .htaccess-Variante und sollte bei speziellen Cache- oder Proxy-Konfigurationen berücksichtigt werden.

Fazit

image² Web Security Headers ist bewusst:

  • minimal
  • serverunabhängig
  • wartungsarm
  • agenturtauglich

Seit Version 2 werden die Header nicht mehr über die .htaccess, sondern direkt über WordPress/PHP gesetzt.

Damit kann dieselbe Plugin-Version unabhängig von der konkreten Apache-/nginx-/Hosting-Konfiguration als image²-Agenturstandard eingesetzt werden.

Eine Content Security Policy bleibt bewusst projektabhängig und wird nicht Bestandteil des Standardplugins.