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 boesartige Website deine Seite unsichtbar einbettet und Besucher dazu verleitet, unbeabsichtigte Aktionen durchzufuehren.
Obwohl es einer der aelteren Sicherheitsheader ist (eingefuehrt 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 muessen.
Wie Clickjacking-Angriffe tatsaechlich funktionieren
Clickjacking ist im Konzept ueberraschend simpel. Angenommen, du betreibst eine WordPress-Seite mit einem Mitgliederbereich, und die Profilseite hat einen "Mein Konto loeschen"-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 ueber seinem "Klicke hier fuer dein Ergebnis"-Button positioniert ist.
Wenn der Besucher auf das klickt, was er fuer einen harmlosen Button auf der Seite des Angreifers haelt, klickt er tatsaechlich den "Mein Konto loeschen"-Button auf deiner versteckten Seite. Wenn der Besucher auf deiner Seite eingeloggt ist (und die meisten Browser behalten Session-Cookies), wird die Aktion ausgefuehrt. Der Besucher hat keine Ahnung, was gerade passiert ist.
Diese Technik wurde in echten Angriffen eingesetzt, um:
- Privatsphaereneinstellungen auf Social-Media-Konten zu aendern
- OAuth-Anwendungen ohne Wissen des Nutzers zu autorisieren
- Auf Werbung zu klicken, um betruegerische Einnahmen zu generieren
- Webcam- oder Mikrofonzugriff in aelteren Browsern zu aktivieren
- Geld in Online-Banking-Oberflaechen zu ueberweisen
Der Angriff funktioniert, weil der Browser keine eingebaute Moeglichkeit hat zu erkennen, dass der iframe boesartig verwendet wird. X-Frame-Options gibt deinem Server eine Moeglichkeit, das Einrahmen komplett abzulehnen.
X-Frame-Options Header-Werte erklaert
Der Header unterstuetzt zwei praktische Werte (plus einen dritten, veralteten):
DENY: Die Seite kann in keinem Frame angezeigt werden, Punkt. Keine Website, einschliesslich deiner eigenen, kann diese Seite in einem iframe einbetten. Dies ist die strikteste Einstellung und funktioniert gut fuer 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 haeufigsten verwendete Wert, weil er deiner eigenen Seite die Nutzung von iframes erlaubt, waehrend externe Seiten blockiert werden.ALLOW-FROM uri: Dieser Wert sollte die Angabe eines einzelnen erlaubten Ursprungs ermoeglichen, der deine Seite einrahmen darf. Er wurde jedoch nie konsistent von Browsern unterstuetzt. Chrome und Safari haben ihn nie implementiert. Firefox hat ihn eine Zeit lang unterstuetzt, dann aber fallen gelassen. Dieser Wert ist praktisch tot und sollte nicht verwendet werden.
Wann DENY vs. SAMEORIGIN bei WordPress verwenden
Fuer die meisten WordPress-Seiten ist SAMEORIGIN die richtige Wahl. Der Grund:
WordPress selbst verwendet intern an mehreren Stellen iframes. Der Theme-Customizer laedt eine Vorschau deiner Seite in einem iframe. Der Medien-Uploader verwendet iframes. Der klassische Editor-Dialog "Medien einfuegen" 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 fuer bestimmte Seiten, auf denen Framing niemals passieren sollte, wie eine eigenstaendige Login-Seite oder eine Zahlungsverarbeitungsseite. Aber als seitenweiter Standard fuer WordPress bietet SAMEORIGIN den Schutz, den du brauchst, ohne die Admin-Funktionalitaet zu beschaedigen.
Wenn du ein Headless-WordPress-Setup betreibst, bei dem die Admin-Oberflaeche 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 ueber Web-Sicherheitsheader illustriert. Die Direktive war Teil der urspruenglichen 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 unterstuetzt
- Das Verhalten war bei den Browsern, die sie unterstuetzten, inkonsistent
Die CSP-Direktive frame-ancestors wurde als ordentlicher Ersatz entworfen, mit Unterstuetzung fuer mehrere Urspruenge und konsistentem Browser-uebergreifendem 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 Flexibilitaet:
Content-Security-Policy: frame-ancestors 'self'Dies entspricht X-Frame-Options: SAMEORIGIN. Aber frame-ancestors unterstuetzt auch mehrere Urspruenge:
Content-Security-Policy: frame-ancestors 'self' https://trusted-partner.com https://another-domain.comDas waere mit X-Frame-Options allein unmoeglich.
Wenn beide Header vorhanden sind, variiert das Browser-Verhalten. Moderne Browser priorisieren generell frame-ancestors gegenueber X-Frame-Options. Die empfohlene Praxis ist jedoch, beide Header fuer maximale Kompatibilitaet zu senden. Aeltere Browser, die CSP nicht verstehen, fallen auf X-Frame-Options zurueck, waehrend moderne Browser frame-ancestors verwenden.
Hier ein Beispiel fuer die gemeinsame Nutzung:
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'X-Frame-Options fuer WordPress einrichten
WordPress sendet tatsaechlich standardmaessig X-Frame-Options: SAMEORIGIN fuer den Admin-Bereich (wp-admin). Dies geschieht in der Datei wp-includes/functions.php ueber die Funktion send_frame_options_header(). Das Frontend deiner Seite erhaelt diesen Header jedoch standardmaessig nicht.
Um ihn seitenweit ueber Apache hinzuzufuegen, trage dies in deine .htaccess-Datei ein:
Header always set X-Frame-Options "SAMEORIGIN"Fuer Nginx:
add_header X-Frame-Options "SAMEORIGIN" always;Du kannst ihn auch ueber 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 muessen (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 prueft
InspectWP prueft, 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 koennte, was Clickjacking-Angriffe gegen deine Besucher ermoeglicht. Der Report zeigt auch den Header-Wert an, wenn er vorhanden ist, damit du ueberpruefen kannst, ob er wie fuer dein Setup angemessen auf SAMEORIGIN oder DENY gesetzt ist.