Clickjacking - нападник вбудовує ваш сайт у невидимий <iframe> на своїй сторінці й розміщує його над власною приманкою: «Натисніть, щоб отримати приз». Користувач думає, що клікає по кнопці нападника, а насправді натискає «Видалити акаунт», «Підтвердити переказ» чи «Надати доступ» на вашому сайті - зі своєю активною сесією.
<!-- сторінка нападника -->
<iframe src="https://bank.example/transfer?to=attacker" style="opacity:0; position:absolute; top:0"></iframe>
<button>Отримати подарунок</button>
Захист - заборонити вбудовувати сторінки у фрейми на чужих сайтах.
1. CSP frame-ancestors - сучасний спосіб:
Content-Security-Policy: frame-ancestors 'none'
Content-Security-Policy: frame-ancestors 'self' https://partner.example
'none'- сторінку не можна вбудувати ніде;'self'- лише на сторінках того самого походження;- можна перелічити довірені домени.
2. X-Frame-Options - старий заголовок, ще корисний для старих браузерів:
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
ALLOW-FROM застарів і сучасними браузерами не підтримується - для вибіркового дозволу лише frame-ancestors. Якщо задано обидва заголовки, браузери з підтримкою CSP використовують frame-ancestors.
Що варто знати:
frame-ancestorsне працює в тегу<meta>- лише в HTTP-заголовку;- захищати потрібно всі сторінки з діями, а не лише головну: найчастіше атакують налаштування облікового запису, підтвердження платежів, сторінки OAuth-згоди;
- JavaScript-захист на кшталт «якщо
top !== self, перейти на верхній рівень» (frame busting) легко обходиться атрибутомsandboxу фреймі нападника - заголовки надійніші; - якщо сайт справді має вбудовуватися (віджети, платіжні форми), - вбудовувати лише окремі сторінки з явним переліком дозволених доменів, а не весь застосунок.
Додатковий бар'єр - cookie сесії з SameSite=Lax чи Strict: у фреймі на чужому сайті браузер не надішле таку cookie, і користувач виявиться неавтентифікованим.