Проверка встраивания iframe

Бесплатный онлайн-инструмент проверки iframe: введите адрес любой веб-страницы, чтобы проверить её заголовки X-Frame-Options и Content-Security-Policy frame-ancestors, узнать, можно ли встроить страницу в iframe, и подтвердить это в реальном времени. История сохраняется только для текущей сессии браузера.

Проверка встраивания в iframe

:

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

Проверено: /
URL Результат HTTP

Предпросмотр

Анализ заголовков — быстрая первичная проверка, но она не выявляет JavaScript frame-busting: если заголовки указывают на «Допускается встраивание», но предпросмотр остаётся пустым, прерывает связь или показывает ошибку, страница небезопасна для встраивания. Предпросмотр в реальном времени даёт окончательный ответ.

История (текущая сессия)

Сохраняется только во вкладке (sessionStorage); удаляется при закрытии вкладки. Никакие данные не отправляются на сервер.

Пока нет проверок в этой сессии.

Как работает проверка

  1. Введите целевой URL и нажмите «Проверить». Сервер запрашивает страницу как реальный запрос iframe (с Sec-Fetch-Dest: iframe) и считывает её заголовки ответа.
  2. Вердикт формируется на основе заголовков X-Frame-Options (DENY / SAMEORIGIN блокируют фрейминг) и Content-Security-Policy frame-ancestors (встраивание с любых сторонних сайтов разрешено только при указании * или универсального шаблона протокола).
  3. Тот же URL загружается в окно предпросмотра, чтобы вы могли убедиться в том, что делает браузер в реальности, включая срабатывания JavaScript frame-busting, которые скрыты в заголовках.

От чего зависит возможность встраивания страницы?

Решение о том, можно ли показывать веб-страницу внутри <iframe> на стороннем сайте, принимает браузер на основе заголовков ответа, отправляемых самой страницей. Данный инструмент выполняет аналогичную проверку на стороне сервера и выдаёт вердикт моментально.

X-Frame-Options — классический заголовок: DENY запрещает встраивание всех страниц, SAMEORIGIN разрешает его только со страниц из того же источника, а ALLOW-FROM удалён из современных браузеров. При отсутствии этого заголовка устаревшие правила не блокируют встраивание.

Content-Security-Policy: frame-ancestors — современная замена. Он указывает источники, которым разрешено встраивать страницу, например frame-ancestors 'self' https:\/\/example.com. Значение * (или просто протокол, например https:) разрешает встраивание любыми родителями по HTTPS; более узкие значения блокируют встраивание сторонними сайтами.

Одних заголовков недостаточно: скрипты на странице могут выполнять защиту от обмана фреймами (сравнивая top !== self и принудительно разрывая вложенность), а страницы авторизации или эндпоинты с геоограничениями могут реагировать иначе на запросы с датацентров. Именно поэтому к каждому результату прикреплён живой предпросмотр.

Быстрый справочник: настройка заголовков ответа

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

Запретить встраивание с любой страницы

X-Frame-Options: DENY Content-Security-Policy: frame-ancestors 'none'

Браузеры отказываются отображать страницу внутри любого iframe — это наиболее строгая защита от кликджекинга.

Разрешить встраивание только от источника того же домена

X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self'

Встраивать могут только страницы с той же схемой, хостом и портом; сторонние ресурсы будут заблокированы.

Разрешить встраивание только от конкретных источников

Content-Security-Policy: frame-ancestors 'self' https:\/\/trusted.example.com

Укажите доверенные источники в директиве frame-ancestors; все остальные будут заблокированы.

Разрешить встраивание с любой страницы

Не устанавливайте X-Frame-Options Content-Security-Policy: frame-ancestors *

Любой сайт может встроить вашу страницу в iframe. Обязательно оцените компромиссы в области безопасности.

Примечание: X-Frame-Options устарел и заменён директивой CSP frame-ancestors. Если оба заголовка присутствуют, приоритет отдаётся CSP — рекомендуется использовать frame-ancestors.

Как сервер определяет, что запрос пришёл из iframe?

Примерно с 2020 года браузеры на базе Chromium и Firefox автоматически добавляют набор заголовков Fetch Metadata ко всем запросам навигации и загрузки подресурсов. Самый полезный для проверки встраивания — Sec-Fetch-Dest: он сообщает серверу, в каком контексте запрашивается ресурс, без какого-либо вмешательства запрашивающей страницы.

  • Sec-Fetch-Dest: document — навигация верхнего уровня, вне любых фреймов.
  • Sec-Fetch-Dest: iframe — запрос загружается внутри элемента <iframe>.
  • Sec-Fetch-Dest: frame — загружается внутри устаревшего тега <frame> (фреймсета).
  • Sec-Fetch-Dest: embed / object — загружается внутри элементов <embed> или <object>.

Данный чекер отправляет собственную проверяющую команду с заголовком Sec-Fetch-Dest: iframe, полностью повторяя запрос реального браузера при встраивании страницы. Таким образом, результат отражает, как целевой сервер действительно реагирует на легитимные запросы <iframe>, а не на обычный произвольный fetch.

Заголовок Sec-Fetch-Dest — это полезный индикатор, но не барьер безопасности: его поддерживают только современные браузеры. Небраузерные клиенты (curl, боты, некоторые WebView-контейнеры и устаревшие браузеры) могут игнорировать его полностью или передавать произвольные значения. Сервер может использовать этот заголовок для журналирования или применения лимитов запросов (rate-limit), однако ни в коем случае не стоит опираться на него в одиночку при оценке безопасности фрейминга. Окончательное решение о том, разрешено ли встраивание, по-прежнему принимают политики X-Frame-Options и CSP frame-ancestors, которые применяются самими браузерами независимо от наличия других заголовков.

Со стороны клиента страница может определить факт нахождения во фрейме даже без анализа заголовков, например сравнив window.top !== window.self (или проверив window.frameElement для страниц из одного источника), после чего предпринять действия: вывести предупреждение или принудительно открыть страницу в главном окне. Эта техника защиты от нежелательного фрейминга (frame-busting) была упомянута ранее, и она срабатывает независимо от содержимых заголовков запроса.

Примеры конфигурации сервера: блокировка встраивания в iframe

Приведённые ниже примеры показывают, как настроить каждый веб-сервер или фреймворк для полной блокировки встраивания в iframe (X-Frame-Options: DENY + CSP frame-ancestors 'none') — это самый строгий вариант из руководства выше.

server {
    location / {
        add_header X-Frame-Options "DENY" always;
        add_header Content-Security-Policy "frame-ancestors 'none'" always;
    }
}
<IfModule mod_headers.c>
    Header always set X-Frame-Options "DENY"
    Header always set Content-Security-Policy "frame-ancestors 'none'"
</IfModule>
app.use((req, res, next) => {
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
  next();
});
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          { key: 'X-Frame-Options', value: 'DENY' },
          { key: 'Content-Security-Policy', value: "frame-ancestors 'none'" },
        ],
      },
    ];
  },
};
class SetFrameOptions
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);
        $response->headers->set('X-Frame-Options', 'DENY');
        $response->headers->set('Content-Security-Policy', "frame-ancestors 'none'");

        return $response;
    }
}
export default {
  async fetch(request) {
    const response = await fetch(request);
    const headers = new Headers(response.headers);
    headers.set('X-Frame-Options', 'DENY');
    headers.set('Content-Security-Policy', "frame-ancestors 'none'");
    return new Response(response.body, { status: response.status, headers });
  },
};

Нужно разрешить встраивать страницу только вашему сайту или короткому списку доверенных источников, а не всем подряд? Замените DENY на SAMEORIGIN, а 'none' на 'self' или явный список источников — остальная конфигурация останется неизменной.

Известные особенности платформ

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

Платформа / сценарий использования Поведение Причина
Страница просмотра YouTube (youtube.com/watch) Заблокировано Вместо этого используйте официальный URL плеера youtube.com/embed/{id} — обычная страница просмотра применяет строгую политику фрейминга.
Страница объекта на картах Google Заблокировано К встраиванию предназначена только специальная ссылка iframe через Maps Embed API (google.com/maps/embed).
Страницы авторизации Google / Microsoft (OAuth) Заблокировано Целенаправленно заблокировано с 2015 года для предотвращения фишинга учётных данных во вкладках <iframe>; процесс авторизации должен выполняться в основном окне или всплывающем окне (popup).
Страницы оплаты (Stripe Checkout, PayPal, большинство банковских шлюзов) Заблокировано Встраивание формы оплаты — классический вектор атаки кликджекинга, поэтому платёжные процессоры блокируют это напрямую.
Страницы репозиториев и файлов GitHub Заблокировано Для всего сайта действует директива frame-ancestors 'none'; вместо <iframe> используйте REST/GraphQL API или сделайте скриншот.
Режим «Публикация в веб» для Notion / Google Документы Встраивается Созданы специально для встраивания: сам продукт предоставляет готовые сниппеты для этой цели.
Статьи в Википедии Встраивается По умолчанию не содержат ограничений X-Frame-Options или CSP, но перед масштабным встраиванием обязательно ознакомьтесь с условиями лицензии и правилами указания авторства.

Типичные случаи использования

  • Определите возможность встраивания стороннего виджета, панели управления или документа в ваш продукт ещё до начала написания кода интеграции.
  • Проверьте, корректно ли ваш сайт отправляет запрошенные вами политики X-Frame-Options или CSP frame-ancestors.
  • Диагностика защиты от кликджекинга: выясните, почему страница отображает `about:blank` или сообщение об отказе внутри iframe.
  • Пакетная проверка потенциальных URL при агрегации контента или интеграции с порталом: используйте историю сеанса для возврата к результатам.
  • Подготовьтесь к аудитам безопасности или тестированию на проникновение, задокументировав политику фрейминга внешних зависимостей.

Часто задаваемые вопросы

Почему страница со статусом «Встраивается» остаётся пустой в окне предпросмотра?
Заголовки ответа разрешают встраивание, но на странице скорее всего используется JavaScript для блокировки фреймов, требуется авторизация или cookies, либо контент меняется в зависимости от посетителя. Доверяйте данным предпросмотра.
Можно ли обойти заголовки X-Frame-Options или CSP?
Нет. Браузер принудительно применяет эти заголовки в целях безопасности (защита от кликджекинга); клиентские обходы ненадёжны. Для встраивания неконтролируемого вами контента попросите владельца сайта добавить ваш origin в директиву `frame-ancestors` или используйте официальное решение для встраивания/API, которое они предоставляют.
В чём разница между директивами DENY и SAMEORIGIN?
DENY блокирует встраивание страницы во все iframe, даже в рамках одного источника; SAMEORIGIN разрешает встраивание только со страниц, использующих ту же схему, хост и порт.
Хранит ли инструмент проверки мои URL-адреса?
История доступна только во вкладке вашего браузера через `sessionStorage` и исчезает при её закрытии. Сервер проверки лишь запрашивает указанный URL для чтения заголовков ответа, не сохраняя данные.
Почему один и тот же URL-адрес может давать разные результаты в разное время?
Сайты могут возвращать разные заголовки в зависимости от пути (path), перенаправлений (redirects), User-Agent, а также в зависимости от правил WAF или A/B-тестов. Выполните проверку повторно, чтобы увидеть текущий статус.