X-Frame-Options ist ein HTTP-Response-Header, der dem Browser mitteilt, ob deine Seite innerhalb eines <iframe>-, <frame>- oder <object>-Elements angezeigt werden darf. Sein Hauptzweck ist die Verhinderung von Clickjacking-Angriffen, einer Angriffsklasse, bei der eine bösartige Website deine Seite unsichtbar einbettet und Besucher dazu verleitet, unbeabsichtigte Aktionen durchzuführen.
Obwohl es einer der älteren Sicherheitsheader ist (eingeführt um 2009), wird X-Frame-Options weiterhin breit eingesetzt und bietet nach wie vor wichtigen Schutz. Schauen wir uns an, warum er wichtig ist, wie er funktioniert und was WordPress-Betreiber wissen müssen.
Wie Clickjacking-Angriffe tatsächlich funktionieren
Clickjacking ist im Konzept überraschend simpel. Angenommen, du betreibst eine WordPress-Seite mit einem Mitgliederbereich, und die Profilseite hat einen „Mein Konto löschen"-Button. Ein Angreifer erstellt eine Seite, die wie ein unterhaltsames Quiz oder Spiel aussieht. Er bettet deine Profilseite in einem unsichtbaren iframe ein, der genau über seinem „Klicke hier für dein Ergebnis"-Button positioniert ist.
Wenn der Besucher auf das klickt, was er für einen harmlosen Button auf der Seite des Angreifers hält, klickt er tatsächlich den „Mein Konto löschen"-Button auf deiner versteckten Seite. Wenn der Besucher auf deiner Seite eingeloggt ist (und die meisten Browser behalten Session-Cookies), wird die Aktion ausgeführt. Der Besucher hat keine Ahnung, was gerade passiert ist.
Diese Technik wurde in echten Angriffen eingesetzt, um:
- Privatsphäreneinstellungen auf Social-Media-Konten zu ändern
- OAuth-Anwendungen ohne Wissen des Nutzers zu autorisieren
- auf Werbung zu klicken, um betrügerische Einnahmen zu generieren
- Webcam- oder Mikrofonzugriff in älteren Browsern zu aktivieren
- Geld in Online-Banking-Oberflächen zu überweisen
Der Angriff funktioniert, weil der Browser keine eingebaute Möglichkeit hat zu erkennen, dass der iframe bösartig verwendet wird. X-Frame-Options gibt deinem Server eine Möglichkeit, das Einrahmen komplett abzulehnen.
X-Frame-Options Header-Werte erklärt
Der Header unterstützt zwei praktische Werte (plus einen dritten, veralteten):
DENY: Die Seite kann in keinem Frame angezeigt werden, Punkt. Keine Website, einschließlich deiner eigenen, kann diese Seite in einem iframe einbetten. Dies ist die strikteste Einstellung und funktioniert gut für Seiten, die niemals gerahmt werden sollten, wie Login-Seiten oder Admin-Panels.SAMEORIGIN: Die Seite kann nur in einem Frame angezeigt werden, wenn die einbettende Seite denselben Ursprung hat (gleiches Protokoll, gleiche Domain und gleicher Port). Dies ist der am häufigsten verwendete Wert, weil er deiner eigenen Seite die Nutzung von iframes erlaubt, während externe Seiten blockiert werden.ALLOW-FROM uri: Dieser Wert sollte die Angabe eines einzelnen erlaubten Ursprungs ermöglichen, der deine Seite einrahmen darf. Er wurde jedoch nie konsistent von Browsern unterstützt. Chrome und Safari haben ihn nie implementiert. Firefox hat ihn eine Zeit lang unterstützt, dann aber fallen gelassen. Dieser Wert ist praktisch tot und sollte nicht verwendet werden.
Wann DENY vs. SAMEORIGIN bei WordPress verwenden
Für die meisten WordPress-Seiten ist SAMEORIGIN die richtige Wahl. Der Grund:
WordPress selbst verwendet intern an mehreren Stellen iframes. Der Theme-Customizer lädt eine Vorschau deiner Seite in einem iframe. Der Medien-Uploader verwendet iframes. Der klassische Editor-Dialog „Medien einfügen" ebenfalls. Wenn du DENY setzt, werden all diese Funktionen nicht mehr funktionieren, weil selbst deine eigene Domain die Seite nicht rahmen darf.
DENY ist sinnvoll für bestimmte Seiten, auf denen Framing niemals passieren sollte, wie eine eigenständige Login-Seite oder eine Zahlungsverarbeitungsseite. Aber als seitenweiter Standard für WordPress bietet SAMEORIGIN den Schutz, den du brauchst, ohne die Admin-Funktionalität zu beschädigen.
Wenn du ein Headless-WordPress-Setup betreibst, bei dem die Admin-Oberfläche auf einer Domain und das Frontend auf einer anderen liegt, musst du hier besonders vorsichtig sein, denn SAMEORIGIN erlaubt nur das Einrahmen vom exakt gleichen Ursprung.
Warum ALLOW-FROM veraltet ist
Die Ablehnung von ALLOW-FROM ist es wert, verstanden zu werden, weil sie einen breiteren Punkt über Web-Sicherheitsheader illustriert. Die Direktive war Teil der ursprünglichen X-Frame-Options-Spezifikation, und die Idee war einfach: einer Seite erlauben zu sagen „nur diese bestimmte Domain darf mich einrahmen." In der Praxis gab es mehrere Probleme:
- Sie akzeptierte nur eine einzelne URI, sodass man nicht mehrere Domains freischalten konnte
- Chrome hat sie nie implementiert (der weltweit meistgenutzte Browser hat sie schlicht ignoriert)
- Safari hat sie ebenfalls nie unterstützt
- Das Verhalten war bei den Browsern, die sie unterstützten, inkonsistent
Die CSP-Direktive frame-ancestors wurde als ordentlicher Ersatz entworfen, mit Unterstützung für mehrere Ursprünge und konsistentem Browser-übergreifendem Verhalten. Wenn du bestimmten externen Domains erlauben musst, deine Seiten einzubetten, ist frame-ancestors der richtige Weg.
X-Frame-Options vs. CSP frame-ancestors
Die frame-ancestors-Direktive des Content-Security-Policy-Headers dient demselben Zweck wie X-Frame-Options, aber mit mehr Flexibilität:
Content-Security-Policy: frame-ancestors 'self'
Dies entspricht X-Frame-Options: SAMEORIGIN. Aber frame-ancestors unterstützt auch mehrere Ursprünge:
Content-Security-Policy: frame-ancestors 'self' https://trusted-partner.com https://another-domain.com
Das wäre mit X-Frame-Options allein unmöglich.
Wenn beide Header vorhanden sind, variiert das Browser-Verhalten. Moderne Browser priorisieren generell frame-ancestors gegenüber X-Frame-Options. Die empfohlene Praxis ist jedoch, beide Header für maximale Kompatibilität zu senden. Ältere Browser, die CSP nicht verstehen, fallen auf X-Frame-Options zurück, während moderne Browser frame-ancestors verwenden.
Hier ein Beispiel für die gemeinsame Nutzung:
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options für WordPress einrichten
WordPress sendet tatsächlich standardmäßig X-Frame-Options: SAMEORIGIN für den Admin-Bereich (wp-admin). Dies geschieht in der Datei wp-includes/functions.php über die Funktion send_frame_options_header(). Das Frontend deiner Seite erhält diesen Header jedoch standardmäßig nicht.
Um ihn seitenweit über Apache hinzuzufügen, trage dies in deine .htaccess-Datei ein:
Header always set X-Frame-Options "SAMEORIGIN"
Für Nginx:
add_header X-Frame-Options "SAMEORIGIN" always;
Du kannst ihn auch über PHP in deinem Theme oder einem Plugin setzen:
add_action('send_headers', function() {
header('X-Frame-Options: SAMEORIGIN');
});
Wenn du Plugins verwendest, die deine Seite in einem iframe auf einer anderen Domain einbetten müssen (manche A/B-Testing-Tools, Live-Chat-Widgets oder Vorschau-Dienste), musst du deinen Ansatz anpassen. Verwende in dem Fall CSP frame-ancestors, um diese spezifischen Domains freizuschalten, anstatt X-Frame-Options komplett zu entfernen.
Was InspectWP prüft
InspectWP prüft, ob deine WordPress-Seite den X-Frame-Options-Header auf ihren Frontend-Seiten sendet. Wenn der Header fehlt, markiert der Report dies als Sicherheitsproblem, weil jede Website deine Seiten in einem iframe einbetten könnte, was Clickjacking-Angriffe gegen deine Besucher ermöglicht. Der Report zeigt auch den Header-Wert an, wenn er vorhanden ist, damit du überprüfen kannst, ob er wie für dein Setup angemessen auf SAMEORIGIN oder DENY gesetzt ist.