Перевірка вбудовування iframe

Безкоштовний онлайн-сервіс для перевірки IFrame: введіть URL будь-якої вебсторінки, щоб проаналізувати заголовки X-Frame-Options та Content-Security-Policy frame-ancestors, з’ясувати, чи можна вбудувати цю сторінку, і підтвердити результат через живий попередній перегляд. Історія зберігається лише протягом поточної сесії браузера.

Перевірка вбудовування 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; будь-які суворіші значення блокуватимуть вбудовування з сторонніх сайтів.

Заголовки — це не весь механізм: скрипти на самій сторінці можуть запускати код для захисту від вбудовування (frame-busting, що порівнює 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, боти, окремі веб-переглядачі та застарілі браузери) можуть повністю пропустити його або надіслати довільне значення. Сервер може логувати такі запити або встановлювати ліміти швидкості на їх основі, але ніколи не повинен покладатися виключно на цей сигнал для визначення безпеки вбудовування; це рішення має базуватися на 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' або конкретний список джерел — решта конфігурації залишиться без змін.

Відомі нюанси роботи платформ

Попри загальні правила роботи з заголовками, деякі відомі платформи мають свої специфічні особливості, про які варто знати, перш ніж робити висновок щодо блокування чи можливості вбудовування лише на основі заголовків.

Платформа / сценарій Поведінка Чому?
Сторінка перегляду YouTube (youtube.com/watch) Заблоковано Натомість використовуйте офіційний URL плеєра youtube.com/embed/{id} — звичайна сторінка перегляду надсилає обмежувальну політику вбудовування.
Сторінка місця в Google Картах Заблоковано Вбудовувати дозволено лише через URL iframe для Maps Embed API (google.com/maps/embed).
Сторінки входу OAuth від Google / Microsoft Заблоковано Навмисно заблоковано з 2015 року для запобігання фішингу облікових даних всередині iframe; процес входу має проходити у вікні верхнього рівня або спливаючому вікні.
Сторінки оформлення платежів (Stripe Checkout, PayPal, більшість банківських шлюзів) Заблоковано Вбудовування форми оплати є класичним вектором клікджекінгу, тому платіжні системи категорично це забороняють.
Сторінки репозиторіїв / файлів GitHub Заблоковано Для всього домену активовано frame-ancestors 'none'; замість iframe скористайтеся REST/GraphQL API або скріншотом.
Сторінки "Опублікувати в Інтернеті" в Notion / Google Docs Можна вбудовувати Вони спеціально розроблені для вбудовування, а сервіс надає готовий код для вставки.
Статті у Вікіпедії Можна вбудовувати За замовчуванням обмежувальні заголовки X-Frame-Options/CSP відсутні, але перед масовим вбудовуванням перевірте ліцензійні умови та вимоги щодо авторства.

Поширені випадки використання

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

Часті питання (FAQ)

Чому сторінка зі статусом «Вбудовувана» (Embeddable) залишається порожньою в попередньому перегляді?
Заголовки відповіді дозволяють фреймінг, але сторінка, ймовірно, містить JavaScript для руйнування фреймів (frame-busting), вимагає авторизації або кукі, або ж демонструє різний контент залежно від відвідувача. Довіряйте результатам попереднього перегляду.
Чи можна обійти заголовки X-Frame-Options або CSP?
Ні. Ці заголовки примусово застосовуються браузером заради безпеки (захист від клікджекінгу); клієнтські обхідні методи є ненадійними. Щоб вбудувати контент, яким ви не керуєте, попросіть власника сайту додати ваш origin до білого списку в директиві frame-ancestors або скористайтеся офіційним рішенням для вбудовування або API, яке вони надають.
У чому різниця між DENY та SAMEORIGIN?
DENY повністю блокує відображення сторінки в будь-якому iframe, навіть якщо він має той самий origin; SAMEORIGIN дозволяє фреймінг лише зі сторінок із таким самим протоколом, хостом і портом.
Чи зберігає інструмент перевірки мої URL-адреси?
Історія зберігається виключно у вашій активній вкладці браузера через sessionStorage та автоматично видаляється після її закриття. Сервер перевірки лише здійснює запит до зазначеного URL для зчитування заголовків відповіді.
Чому одна й та сама URL-адреса дає різні результати в різний час?
Сайти можуть надсилати різні заголовки залежно від шляху (path), після редиректів, залежно від User-Agent, а також на основі A/B експериментів або правил WAF. Запустіть перевірку ще раз, щоб отримати актуальний стан.