Skip to content
← Все статьи

Защита от Clickjacking: X-Frame-Options vs frame-ancestors

Защита от Clickjacking: X-Frame-Options vs frame-ancestors

Clickjacking (UI redress attack) — это атака, при которой злоумышленник встраивает ваш сайт в прозрачный iframe на своей странице и заставляет пользователя кликать по «невидимым» кнопкам: подтвердить платёж, сменить пароль, добавить разрешение. Защита от clickjacking — один из самых простых security-фиксов, но его всё ещё нет у 40% российских сайтов (по данным Security Scanner). Разбираем механику атаки и три слоя защиты: X-Frame-Options, CSP frame-ancestors и JS frame-busting.

Как работает clickjacking

Атакующий создаёт страницу с невидимым iframe вашего сайта поверх фейкового интерфейса. Пользователь думает, что жмёт «Получить приз», а на самом деле кликает «Удалить аккаунт» в своём залогиненом сеансе вашего сайта. Классический пример — Twitter worm 2009, когда злоумышленники заставили пользователей ретвитнуть вредоносный пост одним кликом. Подробнее — OWASP: Clickjacking.

X-Frame-Options (устаревший, но универсальный)

Заголовок X-Frame-Options описан в RFC 7034. Три значения:

X-Frame-Options: DENY

CSP frame-ancestors (современный стандарт)

Директива frame-ancestors в CSP Level 2+ заменяет X-Frame-Options и поддерживает множественные источники:

Content-Security-Policy: frame-ancestors 'none';
# или
Content-Security-Policy: frame-ancestors 'self' https://trusted-partner.com;

Если присутствуют и X-Frame-Options, и frame-ancestors — браузер уважает CSP. Для legacy-клиентов держите оба.

SameSite cookies

Даже если clickjacking прошёл, cookie с атрибутом SameSite=Lax или SameSite=Strict не отправятся в cross-site iframe-запросе. Это второй слой защиты. Детали — в Cookie Security.

Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict

JS frame-busting (не полагайтесь только на него)

if (self !== top) {
  top.location = self.location;
}

Этот код ломается атрибутом sandbox на iframe злоумышленника. Используйте как fallback для браузеров без CSP-поддержки.

Конфигурация

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'"

Express/NestJS:

import helmet from 'helmet';
app.use(helmet.frameguard({ action: 'deny' }));
app.use(helmet.contentSecurityPolicy({
  directives: { frameAncestors: ["'none'"] }
}));

Когда нужен SAMEORIGIN

Если у вас есть legitimate iframe-встройки между поддоменами (например, виджеты в админке), ставьте SAMEORIGIN или frame-ancestors 'self'. Никогда не используйте ALLOWALL — эквивалентно отсутствию защиты.

Проверка

curl -I https://example.com | grep -E "X-Frame-Options|Content-Security"

Или используйте Security Scanner enterno.io — он попробует встроить сайт в iframe и покажет, блокируется ли встройка. Обзор связанных заголовков — в HTTP Security Headers.

FAQ

Нужен ли X-Frame-Options, если есть CSP? Да, для браузеров старше CSP Level 2 (IE 11) и как defense-in-depth.

Можно ли разрешить iframe только одному домену? Только через frame-ancestors https://partner.com — X-Frame-Options ALLOW-FROM не работает.

Защищают ли frame-busting JS? Слабо — атакующий обходит через iframe sandbox или HTML5 double-framing.

Что с мобильными приложениями? WebView не следует CSP по умолчанию; дублируйте проверку на стороне сервера через Referer/Origin.

Вывод

Минимум: добавьте два заголовка и закройте тему. Мониторьте через мониторинг — любой регресс в конфиге будет виден сразу. Связанные темы: Cookie Security, все security headers.

Проверьте ваш сайт прямо сейчас

Проверить →
Другие статьи: SEC
SEC
Subresource Integrity (SRI): защита CDN-скриптов
15.04.2026 · 5 просм.
SEC
CORS: полное руководство по Access-Control-Allow
15.04.2026 · 2 просм.
SEC
CSP (Content Security Policy): настройка с нуля
15.04.2026 · 4 просм.
SEC
WAF (Web Application Firewall): базовый гайд
15.04.2026 · 5 просм.