Chýba X-Frame-Options (clickjacking)
Čo to je
Vaše stránky neposielajú hlavičku X-Frame-Options a ani v CSP nemajú frame-ancestors. Bez nich vás ktokoľvek môže vložiť do <iframe> na cudzom webe.
Prečo je to problém
Útok sa volá clickjacking. Útočník postaví obyčajne vyzerajúcu stránku, na ňu položí váš web v iframe, ten spriehľadní CSS trikom a navrch dá tlačidlo „Vyhrať iPhone“. Návštevník klikne — a v skutočnosti klikol na „Zmazať účet“ vo vašom webe, kam je prihlásený.
Praktické scenáre:
- Zmena hesla (
POST /change-passwordrovnakého účtu, z CSRF chráneného formulára). - One-click nákup — odsúhlasenie dialógu „Confirm purchase“.
- Schválenie OAuth aplikácie.
Ako to opraviť
Existujú dve hlavičky — môžete poslať obe:
X-Frame-Options (staršia, podporujú ju všetky prehliadače)
X-Frame-Options: DENY
# alebo
X-Frame-Options: SAMEORIGINDENY — nikto vás nesmie vložiť do iframe, ani vy sami.SAMEORIGIN — do iframe len z vlastnej domény.
CSP frame-ancestors (modernejšia, jemnejšia)
Content-Security-Policy: frame-ancestors 'none';
# alebo:
Content-Security-Policy: frame-ancestors 'self';
# alebo s allowlistom:
Content-Security-Policy: frame-ancestors 'self' https://partner.example.cz;Keď máte CSP, frame-ancestors má prednosť pred X-Frame-Options.
Konkrétna konfigurácia
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'"Kedy NIE DENY?
Občas web potrebuje byť v iframe — na vlastnom e-shope (košíkový widget), v partnerskom portáli, vo white-label riešení. V takom prípade nepoužívajte DENY, ale dajte konkrétny allowlist cez frame-ancestors.