Кликджекинг обманом заставляет вас нажать кнопку на скрытой странице, лежащей под той, что вы видите. Разберём, как он работает и как надёжно его предотвратить (без шагов атаки).
Что становится мишенью
Всё, что «один клик — готово, и ценно».
| Вероятная мишень | Почему |
|---|---|
| Подтверждение перевода/покупки | Один клик двигает деньги |
| Изменение настроек (видимость, подключённые приложения) | Готовит позднейший захват или доступ к данным |
| OAuth / «Разрешить» на выдачу прав | Молча одобряет привязку аккаунта |
| Подписка / лайк / публикация в соцсети | Злоупотребляют для распространения и накрутки лайков |
Почему это работает
Браузеры могут загрузить другой сайт в iframe и наложить его сверху. Злоумышленник делает этот iframe прозрачным (opacity 0), поэтому пользователь видит только приманку, размещённую под ним. Когда пользователь нажимает «фальшивую кнопку», клик получает настоящая кнопка, лежащая прямо над ней.
Это похоже на CSRF, но CSRF отправляет запрос за кулисами, а кликджекинг заставляет пользователя управлять настоящим экраном — поэтому одни лишь CSRF-токены его не останавливают.
Реальный случай: диалог разрешений браузерного плагина (2008)
В октябре 2008 года Adobe опубликовала бюллетень безопасности (APSA08-08) о проблеме кликджекинга, затрагивающей несколько браузеров. По сообщениям прессы, невидимо наложив диалог настроек Flash Player, сайт мог добиться того, чтобы пользователь, сам того не понимая, разрешил ему доступ к камере и микрофону. Adobe выпустила исправленные версии Flash Player, а в качестве временной меры посоветовала пользователям выбрать «всегда запрещать» в Диспетчере настроек.
Урок: мишень — не только кнопки перевода. Под угрозой любой экран, где один клик передаёт разрешение («Разрешить», «Согласен», «Подключить»). MITRE относит эту слабость к CWE-1021 (Improper Restriction of Rendered UI Layers or Frames — недостаточное ограничение отображаемых слоёв интерфейса или фреймов).
Защита: не позволяйте другим сайтам встраивать ваш сайт
Установите CSP frame-ancestors (самое важное)
Добавьте Content-Security-Policy: frame-ancestors 'self' (вас может фреймить только ваш собственный origin). Если вас никому не нужно встраивать, безопаснее всего 'none'. Перечисляйте домены только для партнёров, которым вы явно разрешаете.
Добавьте также X-Frame-Options (обратная совместимость)
Для старых клиентов отправляйте ещё и X-Frame-Options: DENY (или SAMEORIGIN). Так покрываются и старые, и новые браузеры.
Добавьте шаг подтверждения для критических действий
Закрывайте переводы и выдачу прав повторной аутентификацией, диалогом подтверждения или проверкой намерения — такое сложнее протащить через молчаливое наложение.
Сделайте сеансовые куки SameSite
SameSite=Lax/Strict ограничивает межсайтовую автоотправку. Сам по себе это не полное решение от кликджекинга, но он ослабляет более широкий класс «действие началось с другого сайта».
X-Frame-Options и CSP frame-ancestors
Оба заголовка не дают другим сайтам встраивать ваш, но различаются в деталях.
| X-Frame-Options | CSP 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 или прокси не вырезает заголовок
Как проверить свой сайт
Проверьте инструментом для заголовков
Введите URL своего сайта в проверку заголовков безопасности и посмотрите, возвращаются ли X-Frame-Options и CSP frame-ancestors. Проверьте не только главную страницу, но и страницы настроек после входа, а также страницы переводов или выдачи прав.
Проверьте в инструментах разработчика браузера
Перезагрузите страницу с открытой вкладкой «Сеть» (Network) и посмотрите заголовки ответа HTML. Также убедитесь, что заголовок не отправляется дважды или с противоречащими значениями.
Задайте в одном месте
Если добавлять его ко всем ответам в одном месте (веб-сервер вроде 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
Читать дальше
- Глоссарий: Что такое CSRF · Что такое XSS
- Руководство: Выбор заголовков безопасности (что ещё нужно, а что устарело) (на английском)
- Проверка: Проверка заголовков безопасности · Конструктор CSP