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

Способы обмана, которые используют мошенники для заманивания пользователей на фишинговые сайты и кражу данных, давно перестали ограничиваться типичными поддельными письмами или ссылками. Но, выстраивая систему безопасности, многие владельцы сайтов забывают про кликджекинг (с английского – click jacking).
В этой статье поговорим о том, что это за вид атаки, разберем основные схемы, которые применяют злоумышленники, и как выстроить защиту, чтобы пользователи не стали жертвами обмана на вашем ресурсе.
Объясним на примере: вы заходите на сайт, нажимаете на кнопку, которая выглядит совершенно безобидно, а в этот момент вы же своей мышью подтверждаете: подписку, изменение настроек, выдачу разрешения, лайк, платеж или автозаполнение скрытой формы или скачивание файла с вредоносным ПО. Это и есть клик джекинг.
Когда человек кликает по ссылке, он ожидает перехода на нужную страницу. Но иногда случается подвох: клик ведет совсем не туда, куда думал пользователь. Мошенники размещают прозрачный слой с iFrame поверх страницы, и настоящая кнопка оказывается скрыта под той картинкой или ссылкой, по которой жертва собиралась нажать. Пользователь нажимает на безобидный баннер, а фактически активирует скрытый элемент.
Метод технически несложен и может использоваться в разных сценариях. Например, незаметно для посетителя генерируется большое количество кликов по рекламе, и злоумышленник получает прибыль. Или пока пользователь читает новости, фоново загружается вредоносное расширение или ставится лайк на сомнительную запись в соцсети. Самое опасное, когда жертву убеждают, что она вводит пароль на знакомом сайте, а на самом деле данные вводятся в в форму, контролируемую злоумышленником. Также в комбинации с другими векторами атак злоумышленники могут получить полный доступ к устройству, чтобы отдавать команды или похищать деньги.
И если раньше кликджекинг связывали с сомнительными сайтами, то сейчас кликджекинг встречается где угодно: в мобильных приложениях, браузерных расширениях и даже на внешне вполне приличных площадках. Сверху лежит невидимый слой, а человек даже не догадывается, что каждый его клик уходит в карман мошенников.
Особенно опасен кликджекинг в связке с фишингом — о нем мы писали в другой нашей статье. Пользователь видит привычную форму входа и спокойно вводит логин с паролем, будучи уверенным, что все происходит на знакомом сайте. В реальности же данные уходят прямиком к мошенникам, которые просто подставили свое невидимое окно поверх настоящего.
Несколько лет назад в истории с PayPal был показательный случай clickjacking атаки.Один исследователь безопасности нашел уязвимость, которая позволяла похищать деньги буквально одним кликом. Мошенники могли встроить специальный код в iframe, и жертва, которая уже была авторизована в PayPal, даже не поняла бы, как перевела деньги на сторонний счет.
Самое неприятное, что под удар попадали не только обычные пользователи. Сайты, где прием платежей завязан на PayPal, тоже оказывались в зоне риска. Если бы проблему вовремя не исправили, любой злоумышленник мог попытаться провести платеж с счетов посетителей в произвольных суммах. И никто бы даже не заметил, так как со стороны все выглядит как обычный клик по кнопке.
В 2025 году исследователь Марек Тот обнаружил, что атаке подвержены не только сайты, но и браузерные расширения, которые имеют расширенные права доступа к данным пользователя. Техника называется DOM-based extension clickjacking, и под удар попали одиннадцать популярных менеджеров паролей. Среди них — 1Password, Bitwarden, LastPass и другие известные сервисы.
Схема выглядит так: злоумышленники манипулируют DOM-структурой страницы, чтобы незаметно внедрить интерфейс расширения в прозрачные элементы. Человек видит обычную кнопку вроде «Принять cookies» и нажимает на нее, но в этот момент активируются скрытые функции расширения. Например, запускается автозаполнение скрытых форм с последующей кражей значений или изменение настроек безопасности. Мошенники могут получить логины, пароли, данные банковских карт и даже коды двухфакторной аутентификации.
Из одиннадцати протестированных расширений уязвимыми к краже логинов оказались девять – двое разработчиков до сих пор не закрыли уязвимость в своих расширениях. Пока вендоры разбираются, эксперты советуют отключать автоматическое автозаполнение, использовать ручное подтверждение вставки данных и внимательно проверять домен перед вводом учетных данных. Дополнительным уровнем защиты от классического clickjacking могут быть passkeys: они привязаны к конкретному origin/RP ID, поэтому их нельзя просто «переиспользовать» на другом сайте или в iframe с другим источником. Однако passkeys тоже не являются универсальной защитой: при наличии XSS или ошибок серверной реализации WebAuthn, атака все еще может быть возможна.
Чаще всего мошенники действуют по одной схеме: поверх нормального сайта кладется невидимый слой со своим интерфейсом. Технически это делается по-разному.
Классическая схема с прозрачным слоем поверх страницы – не единственный вариант кликджекинга. Более сложные атаки используют особенности поведения браузера, курсора, двойного клика или перетаскивания элементов. Такие техники встречаются реже, но усложняют обнаружение, потому что пользователь видит один сценарий взаимодействия, а браузер выполняет другой. Например:
Самый надежный способ не попасться на угрозу — всегда держать в голове, что любой клик может быть опасен. Но если без паники, то достаточно соблюдать несколько простых правил.
Когда сайт просит ввести пароль или данные карты, посмотрите на адресную строку и убедитесь, что это действительно тот ресурс, которому можно доверять. Иногда бывает полезно проверить, нет ли на странице странных элементов, которые ведут себя неожиданно, или кнопок, всплывающих из ниоткуда.
Также если баннер или кнопка выглядят подозрительно, лучше просто пройти мимо. Лишний раз проверить, туда ли ведет ссылка, навести курсор и посмотреть на адрес внизу экрана.
Браузеры сейчас многое умеют сами. Современные версии Chrome, Firefox или Safari уже содержат защиты от подобных атак. Однако, они не запрещают встраивание страниц в фрейм сами по себе. Браузер блокирует отображение страницы в iframe только тогда, когда сайт отправляет соответствующие HTTP-заголовки, например X-Frame-Options или Content-Security-Policy с директивой frame-ancestors. Поэтому обновленный браузер важен, но без правильной серверной настройки он не решает проблему полностью.
Защитить сайт от кликджекинга можно с помощью специальных HTTP-заголовков, которые сервер отправляет браузеру вместе со страницей. Один из базовых вариантов — X-Frame-Options. Он сообщает браузеру, можно ли открывать страницу внутри iframe. Если заголовок настроен правильно, браузер заблокирует попытку встроить страницу в чужой интерфейс и не позволит злоумышленнику подменить реальное действие пользователя скрытым кликом.
Для Apache заголовок можно добавить в конфигурацию сайта или в файл .htaccess:
Header always set X-Frame-Options "SAMEORIGIN"
Важно использовать именно set, а не append. Иначе заголовок может продублироваться, а браузер обработает только первый вариант.
Для Nginx настройка добавляется в блок server или location:
add_header X-Frame-Options SAMEORIGIN always;
Ключ always нужен для того, чтобы заголовок отправлялся не только при успешных ответах, но и при редиректах или ошибках, например с кодами 3xx, 4xx и 5xx. Без него заголовок может появляться только при ответах 2xx.
Для IIS настройку обычно добавляют в файл Web.config через пользовательский заголовок:
<system.webServer> <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> </customHeaders> </httpProtocol> </system.webServer>
Это классический способ добавить пользовательский HTTP-заголовок в IIS.
У X-Frame-Options есть два основных значения:
Если сайт не использует собственные iframe и ему не нужно встраивать свои страницы в другие интерфейсы, безопаснее выбрать DENY.
Более современный и гибкий вариант защиты — использовать Content-Security-Policy с директивой frame-ancestors.
Например:
Content-Security-Policy: frame-ancestors 'self'
Такой вариант разрешит встраивание только в пределах того же источника.
Если нужно разрешить несколько доверенных доменов, их можно указать отдельно:
Content-Security-Policy: frame-ancestors 'self' example.com partner.example.com
frame-ancestors считается более гибким механизмом, чем X-Frame-Options. Он позволяет точнее задать, кто имеет право встраивать страницу во фрейм. При этом 'self' работает только при совпадении схемы, домена и порта. То есть https://example.com и http://example.com для браузера будут разными источниками.
Проверить защиту можно через инструменты разработчика в браузере. Для этого нужно открыть сайт, нажать F12, перейти во вкладку Network, выбрать основной запрос страницы и посмотреть заголовки ответа.
Если среди них есть X-Frame-Options или Content-Security-Policy с директивой frame-ancestors, базовая защита от встраивания во фрейм активна.
Для наглядности можно дополнительно попробовать открыть страницу в iframe. Если защита настроена корректно, вместо содержимого появится пустое окно или ошибка загрузки.
На практике лучше использовать оба заголовка: Content-Security-Policy с frame-ancestors для современных браузеров и X-Frame-Options как дополнительную поддержку для старых.
Защита через заголовки — это надежно, но есть еще один эшелон обороны, который работает на опережение. Речь про атрибут SameSite у куки.
Раньше браузеры часто отправляли куки с запросами к домену даже тогда, когда запрос инициировался с другого сайта. Именно на этом основаны CSRF-атаки, кросс-сайт подделка запроса. Сейчас в современных браузерах, включая новые версии Chromium, куки без явно указанного атрибута SameSite обычно обрабатываются как SameSite=Lax. Это снижает часть рисков, но не отменяет необходимости задавать атрибут явно, потому что поведение может отличаться в старых браузерах, встроенных WebView и нестандартных окружениях.
Strict — самый жесткий режим. В этом случае cookie не отправляются с запросами, которые пришли с другого сайта. Даже если пользователь просто перешел по ссылке из поиска, письма или мессенджера, сайт может не распознать его активную сессию до тех пор, пока он не начнет взаимодействовать с самим сайтом.
Такой режим подходит для страниц, где безопасность важнее удобства: панелей управления, платежных форм, смены пароля, административных разделов и других чувствительных действий.
Главный плюс Strict, максимальная защита от кросс-сайтовых сценариев. Главный минус, возможные проблемы с пользовательским опытом. Например, человек переходит по ссылке из письма и вместо авторизованной страницы попадает в состояние, где его сессия не распознана.
Lax — более сбалансированный режим. Cookie не отправляются с опасными кросс-доменными сценариями: POST-запросами, запросами из iframe, скриптов, изображений и других встроенных элементов. Но они отправляются, если пользователь сам кликнул по обычной ссылке и открыл страницу верхнего уровня через GET-переход.
Для большинства сайтов это оптимальный вариант. Он позволяет сохранить нормальный пользовательский сценарий, например переход из поиска, письма или соцсетей, но при этом блокирует значительную часть CSRF-атак.
У Lax есть важные нюансы. Во-первых, в Chrome есть двухминутное исключение: если cookie установлены без атрибута SameSite, браузер в течение короткого времени после установки может обрабатывать их более мягко, чтобы не ломать старые сайты. Этим окном потенциально могут воспользоваться атакующие.
Во-вторых, Lax не защищает от сценариев внутри одного site-контекста, например с поддоменов. Если на blog.example.com есть уязвимость, ее могут попытаться использовать для атаки на example.com.
В-третьих, Lax не закрывает все варианты Login CSRF. Это атака, при которой жертву заставляют войти не в свой аккаунт, а в аккаунт злоумышленника, чтобы затем отслеживать ее действия или подменять сценарий работы с сервисом.
None означает, что cookie будут отправляться всегда, в том числе при кросс-доменных запросах. Это самый открытый режим, поэтому использовать его стоит только тогда, когда без этого действительно нельзя.
Например, SameSite=None может понадобиться для виджета онлайн-чата, который встраивается на чужие сайты, платежного модуля внутри iframe или другого сервиса, который должен корректно работать в стороннем контексте.
У этого режима есть обязательное условие: вместе с SameSite=None нужно указывать атрибут Secure. Это означает, что cookie будут передаваться только по HTTPS. Сам сайт тоже должен работать по HTTPS.
Есть и дополнительные ограничения. Safari с включенной защитой от трекинга может обрабатывать такие cookie строже, чем ожидается, даже если указано SameSite=None; Secure. В некоторых случаях браузер может фактически вести себя так, будто cookie имеют режим Lax или Strict.
Старые браузеры тоже могут работать некорректно. Например, Safari на iOS 12 или UC Browser могут не понимать значение None, из-за чего cookie могут не отправляться так, как задумано.
Для большинства сайтов базовым вариантом стоит считать SameSite=Lax. Он сохраняет удобство для пользователя и одновременно снижает риск CSRF-сценариев.
Для чувствительных разделов лучше использовать SameSite=Strict: админ-панели, платежи, смена пароля, управление аккаунтом.
SameSite=None стоит применять только для тех cookie, которые действительно должны работать в стороннем контексте, например во встроенных виджетах или платежных iframe. При этом обязательно использовать Secure и HTTPS.
В общем виде настройка может выглядеть так:
Set-Cookie: session_id=abc123; SameSite=Lax; Secure; HttpOnly
Здесь SameSite=Lax ограничивает отправку cookie в кросс-сайтовых сценариях, Secure разрешает передачу только по HTTPS, а HttpOnly запрещает доступ к cookie из JavaScript. Вместе эти атрибуты помогают снизить риск кражи сессии и подделки запросов.
Обнаружить кликджекинг на сайте можно двумя путями: ручной проверкой или с помощью специальных инструментов.
Чтобы проверить, есть ли на сайте уязвимости, нужно загрузить его в iframe со своей локальной машины. Создайте простой HTML-файл с таким содержимым:
html
<html> <body> <iframe src="https://example.com" width="500" height="500"></iframe> </body> </html>
Для более глубокой проверки можно использовать специализированные инструменты. Они помогают понять, можно ли встроить страницу в iframe, есть ли на сайте защитные заголовки и насколько реально провести атаку.
После такой проверки важно смотреть не только на сам факт загрузки страницы в iframe, но и на наличие защитных заголовков. Именно они помогают браузеру понять, можно ли показывать страницу внутри другого сайта или это нужно заблокировать.
Ниже перечисляем меры, которые не защищают сами по себе, но могут стать дополнительной подстраховкой:
Обязательно обращайте внимание на то, есть ли в HTTP-заголовках ответа строки:
Если нет, то любой сайт может встроить страницу в iframe и попытаться обмануть посетителя. Приятного и безопасного вам серфинга в сети Интернет!