Defaults.Exposed

Defaults.ExposedИсправления › Защита от кликджекинга (X-Frame-Options)

Как исправить Защита от кликджекинга (X-Frame-Options)

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

Главное для вашего бизнеса: Мошенник может незаметно обернуть ваш живой сайт в фальшивый и украсть деньги или доступ к аккаунтам у ваших авторизованных клиентов — а клиент будет уверен, что это сделал ваш сайт. Исправление бесплатно и занимает у разработчика около 15 минут; оставить эту дыру открытой — это известный пробел, который и преступники, и осторожные покупатели замечают за секунды.

Во что это может вам обойтись

Почему это важно. Это бесплатная однострочная настройка, которая добавляется за минуты и закрывает целый класс уловок, нацеленных на ваших авторизованных клиентов. По нашей оценке это значимая для баллов проверка веб-безопасности с высокой степенью серьёзности, потому что отсутствие заголовка оставляет известную, легко проверяемую дыру, которую преступники автоматизируют, а покупатели специально ищут.

Что это, простыми словами

Когда кто-то заходит на ваш сайт, его браузеру можно дать команду также загрузить ваш сайт внутри другого сайта — как маленькое окно, встроенное в большую страницу. Звучит безобидно, и иногда так и есть. Но именно это и есть механизм атаки под названием кликджекинг.

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

Защита от кликджекинга — это короткая невидимая инструкция, которую ваш сайт отправляет браузеру каждого посетителя и которая по сути говорит:

«Не позволяй другим сайтам загружать меня внутри себя. Если кто-то попытается — откажи.»

Современные браузеры подчиняются этому автоматически. С включённой защитой уловка просто не работает — встроенная копия вашего сайта отказывается загружаться. Без неё ваш сайт становится свободной добычей для использования в качестве скрытого слоя в мошеннической схеме, и попавшийся клиент свяжет всё это с вашим брендом, а не с брендом злоумышленника.

Во что это может вам обойтись

Это реалистичные повседневные сценарии. Мы никогда не называем реальные компании; это иллюстрации того, как используется эта дыра.

  1. Невидимое «подтвердить». Клиент авторизован в личном кабинете в одной вкладке. Он попадает на страницу (из рекламы, письма, результата поиска), которая обещает что-то заманчивое и показывает большую кнопку «Продолжить». Под этой кнопкой спрятан ваш настоящий элемент «Подтвердить перевод» или «Сменить email», загруженный из его собственной авторизованной сессии. Он нажимает «Продолжить» — и неосознанно одобряет изменение в своём реальном аккаунте у вас. И для него, и для вашей поддержки это выглядит так, будто он сделал это на вашем сайте.

  2. Угон настроек. Злоумышленник встраивает вашу страницу настроек аккаунта и накладывает поверх неё безобидную игру или опрос. Несколько кликов в нужных местах тихо меняют настройку — добавляют email злоумышленника как адрес восстановления, выдают разрешение приложению или отключают оповещение безопасности. Аккаунт тихо скомпрометирован, и в момент происходящего ничто не выглядело неправильно.

  3. Сделка, которая буксует. Крупный клиент присылает свою стандартную анкету по безопасности перед подписанием. Одна строка спрашивает, настроена ли у вас защита от встраивания (X-Frame-Options / CSP frame-ancestors). Вашему ИТ-специалисту приходится ответить «нет», и закупка ставится на паузу, пока вы спешно настраиваете бесплатную 15-минутную функцию, которая теперь выглядит тревожным флагом на глазах у покупателя.

  4. Кампания «бренд-как-приманка». Поскольку ваши настоящие, доверенные страницы можно встроить, злоумышленник использует ваш вход или оформление заказа как убедительный слой в более широкой фишинговой кампании. Попавшиеся клиенты винят не безликого злоумышленника — они запоминают это как случай, когда «ваш сайт» позволил их обмануть.

  5. Отметка аудита. Сканер страховщика или аудитор, проверяющий вашу защищённость, перечисляет отсутствие защиты от кликджекинга среди находок. Это хрестоматийный пункт базовой гигиены; его наличие в отчёте сигнализирует, что простые бесплатные меры не были приняты — а это окрашивает оценку всей остальной вашей безопасности.

Сквозная мысль: ущерб ложится на реального авторизованного клиента, делающего то, чего он не намеревался, — и несёт ваше имя, а не имя злоумышленника.

Что это на самом деле

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

1. Старый заголовок — X-Frame-Options:

X-Frame-Options: SAMEORIGIN

Это давно существующий, широко поддерживаемый механизм. Он принимает одно из двух практичных значений:

2. Современный заголовок — Content-Security-Policy frame-ancestors:

Content-Security-Policy: frame-ancestors 'self';

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

Как выглядит «хорошо»

Самая надёжная схема использует оба: frame-ancestors для современных браузеров (и ради точности при указании разрешённых вставщиков) и X-Frame-Options: SAMEORIGIN как запасной вариант для старых клиентов. Нашу проверку удовлетворяет и любой из них по отдельности — но поскольку оба бесплатны и занимают те же несколько минут, нет причин не настроить оба.

Одна важная деталь, которую должен знать ваш разработчик: заголовок Content-Security-Policy-Report-Only ничего не применяет — он только сообщает о нарушениях. Чтобы защита от кликджекинга действительно вступила в силу, она должна исходить из применяющего заголовка (обычного Content-Security-Policy с frame-ancestors или X-Frame-Options), а не из режима «только отчёт».

Как это исправить (бесплатно, ~15 минут)

Передайте этот раздел тому, кто ведёт ваш сайт, — ИТ-специалисту, веб-разработчику или поддержке хостинга. Исправление бесплатно. Это один-два заголовка ответа или правило в CDN. Покупать ничего не нужно.

Проверка проходит при наличии либо заголовка X-Frame-Options (со значением DENY или SAMEORIGIN), либо директивы CSP frame-ancestors. Рекомендуемая схема «с запасом» добавляет оба.

Шаг 1 — Решите, насколько строго

Шаг 2 — Добавьте заголовки (выберите свою платформу)

Nginx — внутри блока server:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "frame-ancestors 'self';" always;

Apache — убедитесь, что включён mod_headers, затем в виртуальном хосте:

Header always set X-Frame-Options "SAMEORIGIN"
Header always set Content-Security-Policy "frame-ancestors 'self';"

Microsoft IIS — в web.config внутри <customHeaders>:

<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="Content-Security-Policy" value="frame-ancestors 'self';" />

Cloudflare (или похожий CDN): перейдите в Rules → Transform Rules → Modify Response Header и добавьте два правила, которые задают X-Frame-Options равным SAMEORIGIN и Content-Security-Policy равным frame-ancestors 'self'; для всех ответов. Это самый простой путь, если у вас нет прямого доступа к серверу.

Уже отправляете Content-Security-Policy по другим причинам? Не создавайте второй заголовок CSP — добавьте frame-ancestors в существующую политику. Два заголовка CSP могут конфликтовать.

Конструкторы сайтов (Squarespace, Wix, Shopify и подобные): эти платформы часто настраивают защиту от встраивания за вас, поэтому вы можете уже проходить проверку без каких-либо действий. Если наша проверка это отметила, нужный механизм обычно находится в настройках безопасности платформы, либо вы добавляете его на CDN перед сайтом. (Примечание: Google Workspace и Microsoft 365 управляют вашей почтой, а не сайтом — этот заголовок ставится там, где реально размещён ваш публичный сайт, а не в админке Workspace/365.)

Шаг 3 — Перезагрузите и проверьте

Перезагрузите веб-сервер или разверните правило CDN, затем откройте ваш живой сайт и проверьте заголовки ответа — инструменты разработчика браузера → вкладка Network → клик по запросу страницы → Response Headers, либо любой бесплатный инструмент проверки заголовков. Убедитесь, что заголовок(и) появляются на реальных ответах страниц, а не только на главной. Затем перезапустите проверку.

Частые ошибки

Частые вопросы

Я не технарь — могу ли я разобраться с этим сам?

Техническую часть делать вам не нужно. Это единственная настройка, добавляемая на сервер вашего сайта или в CDN, и любой веб-разработчик или ИТ-подрядчик добавит её за несколько минут. Передайте им раздел «Как это исправить» ниже — там точно сказано, что добавить. Исправление бесплатно; мы берём оплату только если вы захотите, чтобы мы и дальше следили, что настройка остаётся на месте.

Не помешает ли это моему собственному сайту или легитимным партнёрам показывать мои страницы?

Только если задать слишком строго. Обычная настройка («SAMEORIGIN» или «frame-ancestors self») по-прежнему позволяет вашему сайту встраивать собственные страницы как обычно — она блокирует только внешние сайты. Если настоящему партнёру нужно встроить одну конкретную вашу страницу, разработчик может разрешить именно этот источник, продолжая блокировать всех остальных.

Мы малый бизнес — кто-то правда станет нас атаковать?

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

Как на самом деле выглядит «хорошо»?

Либо заголовок X-Frame-Options со значением SAMEORIGIN (или DENY), либо Content-Security-Policy с директивой frame-ancestors — в идеале и то, и другое. Наша проверка проходит, если присутствует хотя бы одно. Более современный и гибкий механизм — frame-ancestors; X-Frame-Options — это старый заголовок, который всё ещё охватывает часть устаревших браузеров, поэтому надёжная схема «с запасом» использует оба.

Разве это не то же самое, что замочек SSL или HTTPS?

Нет — они защищают от совершенно разных вещей. HTTPS шифрует соединение, чтобы никто не мог прочитать его в пути. Защита от кликджекинга вообще не даёт загружать ваши страницы внутри чужого сайта. У вас может быть идеальный замочек и при этом полная уязвимость к кликджекингу. Это отдельные проверки, и нужны обе.

Если мы это не исправим, понизит ли это нашу оценку?

Да. Это оценочная проверка веб-безопасности, а не информационная — отсутствие заголовка стоит баллов и оценивается как высокая степень серьёзности, потому что напрямую подставляет ваших авторизованных клиентов под мошенничество. Это также одни из самых дешёвых баллов для возврата: один бесплатный заголовок и около 15 минут работы разработчика.