Clickjacking Schutz X Frame Options
Clickjacking-Schutz: X-Frame-Options
Clickjacking versteckt bösartige Klicks unter legitimen Elementen. Lernen Sie, wie Sie Ihre Website vor Frame-Embedding schützen.
Was ist Clickjacking?
Angreifer-Website ┌─────────────────────────────────────┐ │ "Gewinne ein iPhone!" │ │ │ │ ┌─────────────────────────────┐ │ │ │ Ihre Bank (transparent) │ │ │ │ ┌─────────────────────────┐ │ │ │ │ │ [Überweisung bestätigen]│ │ │ ← Versteckter Button │ │ └─────────────────────────┘ │ │ │ └─────────────────────────────┘ │ │ │ │ [ HIER KLICKEN! ] │ ← Sichtbarer "Gewinn"-Button └─────────────────────────────────────┘ Der User klickt vermeintlich auf "Gewinn", aber eigentlich auf "Überweisung bestätigen"
X-Frame-Options Header
| Wert | Bedeutung |
|---|---|
DENY |
Seite kann nie in einem Frame angezeigt werden |
SAMEORIGIN |
Nur von gleicher Domain einbettbar |
ALLOW-FROM uri |
Nur von angegebener URI (veraltet!) |
Konfiguration
Nginx
# In nginx.conf oder server block add_header X-Frame-Options "SAMEORIGIN" always; # Oder komplett verbieten add_header X-Frame-Options "DENY" always;
Apache
# In .htaccess oder VirtualHost Header always set X-Frame-Options "SAMEORIGIN" # Oder Header always set X-Frame-Options "DENY"
PHP
<?php
header('X-Frame-Options: SAMEORIGIN');
Node.js (Express)
// Mit Helmet (empfohlen)
const helmet = require('helmet');
app.use(helmet.frameguard({ action: 'sameorigin' }));
// Manuell
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
next();
});
CSP frame-ancestors (Modern)
Content-Security-Policy bietet mehr Kontrolle:
# Kein Embedding erlaubt Content-Security-Policy: frame-ancestors 'none'; # Nur gleiche Origin Content-Security-Policy: frame-ancestors 'self'; # Bestimmte Domains erlauben Content-Security-Policy: frame-ancestors 'self' https://trusted.com https://partner.de;
Konfiguration
# Nginx
add_header Content-Security-Policy "frame-ancestors 'self'" always;
# Apache
Header always set Content-Security-Policy "frame-ancestors 'self'"
# PHP
header("Content-Security-Policy: frame-ancestors 'self'");
Beide Header kombinieren
# Für maximale Kompatibilität beide setzen # Nginx add_header X-Frame-Options "SAMEORIGIN" always; add_header Content-Security-Policy "frame-ancestors 'self'" always; # Apache Header always set X-Frame-Options "SAMEORIGIN" Header always set Content-Security-Policy "frame-ancestors 'self'"
JavaScript Frame-Busting (Fallback)
// Zusätzlicher Schutz (nicht allein verlassen!)
if (window.top !== window.self) {
window.top.location = window.self.location;
}
// Oder moderner
<style>
html { display: none; }
</style>
<script>
if (self === top) {
document.documentElement.style.display = 'block';
} else {
top.location = self.location;
}
</script>
⚠️ Achtung:
JavaScript Frame-Busting kann umgangen werden. Verwenden Sie immer HTTP-Header als primären Schutz!
Wann Embedding erlauben?
# Wenn Ihre Seite eingebettet werden soll (z.B. Widgets): # Nur bestimmte Partner Content-Security-Policy: frame-ancestors https://partner1.com https://partner2.com; # Für iframe-Widgets separate Endpoints erstellen # /embed/widget - mit Embedding erlaubt # /app - ohne Embedding (X-Frame-Options: DENY)
Testen
# Header prüfen curl -I https://example.com | grep -i "frame\|content-security" # Oder mit Browser DevTools: # Network Tab → Response Headers # Test mit iframe <iframe src="https://example.com"></iframe> # Sollte blockiert werden wenn Schutz aktiv
💡 Tipp:
Prüfen Sie Ihre Security-Header mit dem Enjyn Domain Toolkit.