Глоссарий

Что такое кликджекинг? Атака, заставляющая нажимать кнопки на прозрачной странице, наложенной поверх другой

Кликджекинг невидимо накладывает настоящую страницу поверх чужого сайта, чтобы пользователь нажал скрытые кнопки. Защита: CSP frame-ancestors и X-Frame-Options.

Опубликовано 2026-06-10 Обновлено 2026-10-06 7 мин чтения
На этой странице

Кликджекинг обманом заставляет вас нажать кнопку на скрытой странице, лежащей под той, что вы видите. Разберём, как он работает и как надёжно его предотвратить (без шагов атаки).

Что становится мишенью

Всё, что «один клик — готово, и ценно».

Вероятная мишеньПочему
Подтверждение перевода/покупкиОдин клик двигает деньги
Изменение настроек (видимость, подключённые приложения)Готовит позднейший захват или доступ к данным
OAuth / «Разрешить» на выдачу правМолча одобряет привязку аккаунта
Подписка / лайк / публикация в соцсетиЗлоупотребляют для распространения и накрутки лайков

Почему это работает

Браузеры могут загрузить другой сайт в iframe и наложить его сверху. Злоумышленник делает этот iframe прозрачным (opacity 0), поэтому пользователь видит только приманку, размещённую под ним. Когда пользователь нажимает «фальшивую кнопку», клик получает настоящая кнопка, лежащая прямо над ней.

Страница злоумышленника: «Вы выиграли приз — нажмите ниже!»
= прозрачный iframe настоящей страницы банка/настроек сверху
↓ пользователь нажимает видимую кнопку-приманку
на самом деле нажимается настоящая кнопка «Подтвердить» прямо над ней
↓ под собственным сеансом пользователя
перевод / изменение настроек / согласие выполняется как «действие пользователя»
Злоумышленник невидимо накладывает настоящий сайт; видна только приманка. Клик попадает на прозрачную настоящую страницу.

Это похоже на CSRF, но CSRF отправляет запрос за кулисами, а кликджекинг заставляет пользователя управлять настоящим экраном — поэтому одни лишь CSRF-токены его не останавливают.

Реальный случай: диалог разрешений браузерного плагина (2008)

В октябре 2008 года Adobe опубликовала бюллетень безопасности (APSA08-08) о проблеме кликджекинга, затрагивающей несколько браузеров. По сообщениям прессы, невидимо наложив диалог настроек Flash Player, сайт мог добиться того, чтобы пользователь, сам того не понимая, разрешил ему доступ к камере и микрофону. Adobe выпустила исправленные версии Flash Player, а в качестве временной меры посоветовала пользователям выбрать «всегда запрещать» в Диспетчере настроек.

Урок: мишень — не только кнопки перевода. Под угрозой любой экран, где один клик передаёт разрешение («Разрешить», «Согласен», «Подключить»). MITRE относит эту слабость к CWE-1021 (Improper Restriction of Rendered UI Layers or Frames — недостаточное ограничение отображаемых слоёв интерфейса или фреймов).

Защита: не позволяйте другим сайтам встраивать ваш сайт

1

Установите CSP frame-ancestors (самое важное)

Добавьте Content-Security-Policy: frame-ancestors 'self' (вас может фреймить только ваш собственный origin). Если вас никому не нужно встраивать, безопаснее всего 'none'. Перечисляйте домены только для партнёров, которым вы явно разрешаете.

2

Добавьте также X-Frame-Options (обратная совместимость)

Для старых клиентов отправляйте ещё и X-Frame-Options: DENY (или SAMEORIGIN). Так покрываются и старые, и новые браузеры.

3

Добавьте шаг подтверждения для критических действий

Закрывайте переводы и выдачу прав повторной аутентификацией, диалогом подтверждения или проверкой намерения — такое сложнее протащить через молчаливое наложение.

4

Сделайте сеансовые куки SameSite

SameSite=Lax/Strict ограничивает межсайтовую автоотправку. Сам по себе это не полное решение от кликджекинга, но он ослабляет более широкий класс «действие началось с другого сайта».

X-Frame-Options и CSP frame-ancestors

Оба заголовка не дают другим сайтам встраивать ваш, но различаются в деталях.

X-Frame-OptionsCSP frame-ancestors
ЗначенияDENY (запретить всё) / SAMEORIGIN (только тот же origin)'none' / 'self' / список разрешённых доменов
Несколько разрешённых встраивающих сайтовНевозможно (ALLOW-FROM не работает в современных браузерах)Возможно
Задание через тег metaНе действуетНе действует
Если присутствуют обаИгнорируется поддерживающими браузерамиИмеет приоритет
РольЗапасной вариант для старых браузеровОсновная защита сегодня

Отправляя оба, держите их смысл согласованным: сочетайте frame-ancestors 'none' с DENY, а frame-ancestors 'self' — с SAMEORIGIN.

Частые ошибки настройки

  • Считать, что CSP default-src это покрывает. frame-ancestors не наследует значение от default-src. Даже с default-src 'none' встраивание остаётся разрешённым, пока вы не пропишете frame-ancestors
  • Указывать в теге meta: <meta http-equiv> здесь не действует, поэтому отправляйте это как заголовок ответа
  • Оставить Content-Security-Policy-Report-Only: он только сообщает о нарушениях и не блокирует встраивание. Убедившись, что всё работает, переключитесь на применяемый заголовок
  • Задать только на части страниц: часто проверяют главную страницу и пропускают страницу входа, страницы настроек или страницы ошибок. Также убедитесь, что CDN или прокси не вырезает заголовок

Как проверить свой сайт

1

Проверьте инструментом для заголовков

Введите URL своего сайта в проверку заголовков безопасности и посмотрите, возвращаются ли X-Frame-Options и CSP frame-ancestors. Проверьте не только главную страницу, но и страницы настроек после входа, а также страницы переводов или выдачи прав.

2

Проверьте в инструментах разработчика браузера

Перезагрузите страницу с открытой вкладкой «Сеть» (Network) и посмотрите заголовки ответа HTML. Также убедитесь, что заголовок не отправляется дважды или с противоречащими значениями.

3

Задайте в одном месте

Если добавлять его ко всем ответам в одном месте (веб-сервер вроде nginx или Caddy, обратный прокси или фреймворк), не будет ни пропусков, ни дублей. Если вы пишете новую CSP, конструктор CSP поможет собрать политику, включающую frame-ancestors.

Мнение этого сайта: одна строка заголовка — самая действенная мера, поэтому сперва проверьте свой сайт

Защита от кликджекинга — это не сложный код; это одна-две строки заголовка ответа, запрещающие встраивание. Применяйте их по всему сайту на уровне фреймворка или обратного прокси (Caddy/nginx), чтобы ничего не проскользнуло. Самая частая ошибка — заголовок, который вы считали настроенным, но которого на самом деле нет, поэтому после настройки убедитесь по шагам выше, что он действительно возвращается.

Источники (первичные)

  • OWASP, «Clickjacking Defense Cheat Sheet» — cheatsheetseries.owasp.org (frame-ancestors, X-Frame-Options, SameSite; ALLOW-FROM больше не работает; теги meta не действуют; пределы фреймбастинга)
  • MDN, «CSP: frame-ancestors» — developer.mozilla.org (допустимые значения, нет наследования от default-src, не поддерживается в meta)
  • RFC 7034, «HTTP Header Field X-Frame-Options» — rfc-editor.org
  • IPA, «Как защитить свой веб-сайт, 1.9 Кликджекинг» (на японском) — ipa.go.jp
  • Adobe, «Security Advisory for Flash Player (APSA08-08)» (7 октября 2008) — adobe.com
  • Computerworld, «Clickjackers could hijack webcams, microphones, Adobe warns» (октябрь 2008) — computerworld.com (мишенью был диалог разрешений камеры и микрофона)
  • MITRE, «CWE-1021: Improper Restriction of Rendered UI Layers or Frames» — cwe.mitre.org

Читать дальше

Классификация

CWE классифицирует типы слабостей, из-за которых возникают уязвимости; MITRE ATT&CK классифицирует техники атакующих. Обе системы ведёт MITRE, и они широко используются для разметки уязвимостей и правил обнаружения.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QЧто позволяет кликджекинг?
A

Клик, который пользователь делает «намеренно», попадает на кнопку настоящей страницы, лежащей под ним. Злоупотребляют критическими действиями в один клик: денежные переводы, изменения настроек, выдача разрешений, подписка/лайк в соцсети, кнопки согласия. Он не крадёт пароль — он заставляет уже вошедшего пользователя выполнить действие.

QКакая защита главная?
A

Отказаться встраиваться во фрейм чужого сайта. Установите директиву CSP frame-ancestors в 'self' (или только разрешённые домены) в заголовках ответа и добавьте X-Frame-Options: DENY для обратной совместимости. Это убирает поверхность, нужную для наложения.

QДостаточно ли JavaScript-фреймбастинга?
A

Нет. У старых скриптов «вырвись, если я в iframe» много обходов, и они не помогают, когда JS отключён. Надёжная защита — серверные заголовки (frame-ancestors / X-Frame-Options), которые говорят браузеру отказаться от встраивания.

QX-Frame-Options или CSP frame-ancestors: что использовать?
A

Отправляйте оба с одинаковым смыслом — это стандартная практика. В frame-ancestors можно перечислить несколько разрешённых встраивающих сайтов, и если присутствуют оба заголовка, поддерживающие браузеры применяют frame-ancestors. X-Frame-Options — запасной вариант для старых браузеров. Сочетайте 'none' с DENY, а 'self' — с SAMEORIGIN.

QМожно ли задать это через HTML-тег meta?
A

Нет. frame-ancestors не действует в элементе meta, и X-Frame-Options в элементе meta тоже игнорируется. Оба нужно отправлять как заголовки HTTP-ответа, настраивая их в веб-сервере, обратном прокси или фреймворке.

QЧто делать, если нужно разрешить встраивание страниц другим моим сайтам или партнёру?
A

Перечислите разрешённые стороны в frame-ancestors (например, frame-ancestors 'self' https://partner.example). ALLOW-FROM в X-Frame-Options не работает в современных браузерах, поэтому не полагайтесь на него для списка разрешений. Ограничьте разрешение страницами и доменами, которым встраивание действительно нужно.