Chybí X-Frame-Options (clickjacking)
Co to je
Vaše stránky neposílají hlavičku X-Frame-Options ani v CSP nemají frame-ancestors. Bez nich vás kdokoliv může vložit do <iframe> na cizím webu.
Proč je to problém
Útok se jmenuje clickjacking. Útočník postaví obyčejně vypadající stránku, na ní položí váš web v iframu, ten zprůhlední CSS trikem a navrch dá čudlík „Vyhrát iPhone“. Návštěvník klikne — a ve skutečnosti klikl na „Smazat účet“ na vašem webu, kam je přihlášený.
Praktické scénáře:
- Změna hesla (
POST /change-passwordze stejného účtu, i z formuláře chráněného proti CSRF). - One-click nákup — skryté tlačítko „Confirm purchase“.
- Schválení OAuth aplikace.
Jak to opravit
Existují dvě hlavičky — můžete poslat obě:
X-Frame-Options (starší, podporují všechny prohlížeče)
X-Frame-Options: DENY
# nebo
X-Frame-Options: SAMEORIGINDENY — nikdo vás nesmí vložit do iframu, ani vy sami.SAMEORIGIN — do iframu jen z vlastní domény.
CSP frame-ancestors (modernější, granulárnější)
Content-Security-Policy: frame-ancestors 'none';
# nebo:
Content-Security-Policy: frame-ancestors 'self';
# nebo s allowlistem:
Content-Security-Policy: frame-ancestors 'self' https://partner.example.cz;Když máte CSP, frame-ancestors má přednost před X-Frame-Options.
Konkrétní konfigurace
nginx:
add_header X-Frame-Options "DENY" always;
add_header Content-Security-Policy "frame-ancestors 'none'" always;Apache:
Header always set X-Frame-Options "DENY"
Header always set Content-Security-Policy "frame-ancestors 'none'"Kdy NE-DENY?
Občas web potřebuje být v iframu — na vlastním e-shopu (košíkový widget), v partnerském portálu, ve white-label řešení. V tom případě nepoužívejte DENY, ale dejte konkrétní allowlist přes frame-ancestors.