Sprawdzanie osadzania iframe
Darmowe narzędzie online do sprawdzania iframe: wprowadź adres URL dowolnej witryny, aby sprawdzić jej nagłówki X-Frame-Options oraz Content-Security-Policy frame-ancestors, dowiedz się, czy strona może być osadzona w iframe i potwierdź rezultat dzięki podglądowi na żywo. Historia jest przechowywana tylko w bieżącej sesji przeglądarki.
Historia (ta sesja)
Zapisane tylko w tej karcie (sessionStorage); zostanie usunięte po jej zamknięciu. Nic nie jest przesyłane na serwer.
Jak działa sprawdzenie
- Wprowadź docelowy adres URL i kliknij Sprawdź. Serwer pobiera stronę jako rzeczywiste żądanie iframe (z nagłówkiem Sec-Fetch-Dest: iframe) oraz odczytuje jego nagłówki odpowiedzi.
- Werdykt opiera się na nagłówku X-Frame-Options (DENY / SAMEORIGIN blokują osadzanie) oraz Content-Security-Policy frame-ancestors (tylko `*` lub wildcard dla konkretnego schematu pozwala na osadzanie przez dowolne strony zewnętrzne).
- Ten sam adres URL jest ładowany w elemencie podglądu na żywo, dzięki czemu możesz zweryfikować rzeczywiste zachowanie przeglądarki, w tym działanie mechanizmów JS zapobiegających osadzaniu, których nie wychwytują nagłówki.
Co decyduje o tym, czy strona może być osadzona?
To, czy strona internetowa może być wyświetlana w obrębie elementu <iframe> na innej witrynie, decyduje przeglądarka, bazując na nagłówkach odpowiedzi wysyłanych bezpośrednio przez tę stronę. To narzędzie wykonuje identyczną analizę po stronie serwera i natychmiast dostarcza werdykt.
X-Frame-Options to klasyczny nagłówek: DENY zabrania osadzania na każdej stronie, SAMEORIGIN zezwala jedynie witrynom z tego samego źródła na jej osadzanie, a ALLOW-FROM zostało usunięte z nowoczesnych przeglądarek. Gdy nagłówek ten brakuje, starsze mechanizmy nie blokują osadzania.
Content-Security-Policy frame-ancestors to nowoczesny zamiennik. Wylicza źródła uprawnione do osadzania strony — na przykład frame-ancestors 'self' https://example.com. Wartość * (lub sam protokół, np. https:) zezwala na dowolnego rodzica HTTPS; każde bardziej szczegółowe ustawienie blokuje osadzanie przez strony osób trzecich.
Same nagłówki nie opisują całej sytuacji: skrypty strony mogą uruchamiać kod uniemożliwiający osadzanie w ramkach (porównujący top !== self i wymuszający przejście do pełnego okna), a strony logowania lub punkty końcowe z restrykcjami geograficznymi mogą reagować inaczej na żądania pochodzące z centrów danych. Dlatego każdy wynik uwzględnia również podgląd na żywo.
Szybki przewodnik: konfiguracja nagłówków odpowiedzi
Jeśli kontrolujesz witrynę, zarządzaj osadzaniem bezpośrednio poprzez nagłówki odpowiedzi.
Zablokuj osadzanie z dowolnej strony
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
Przeglądarki odmówią renderowania strony w jakimkolwiek elemencie iframe — jest to najsurowsza forma ochrony przed clickjackiem.
Zezwalaj tylko na osadzanie z tego samego źródła
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
Tylko strony posiadające ten sam protokół, domenę i port mogą ją osadzać; treści zewnętrznych witryn są blokowane.
Zezwalaj tylko na określone źródła
Content-Security-Policy: frame-ancestors 'self' https://trusted.example.com
Dodaj zaufane źródła do dyrektywy frame-ancestors; wszystkie pozostałe zostaną zablokowane.
Zezwalaj na osadzanie z dowolnej witryny
Nie ustawiaj nagłówka X-Frame-Options
Content-Security-Policy: frame-ancestors *
Każda witryna może osadzić stronę w elemencie iframe. Oceń kompromis bezpieczeństwa.
Uwaga: Nagłówek X-Frame-Options wygasł na rzecz dyrektywy CSP frame-ancestors. Przy obecności obu, pierwszeństwo ma CSP — zalecamy stosowanie frame-ancestors.
W jaki sposób serwer wykrywa, że żądanie pochodzi z iframe'a?
Od około 2020 roku przeglądarki oparte na silnikach Chromium i Firefox automatycznie dołączają zestaw nagłówków metadanych żądań Fetch do każdej operacji nawigacyjnej oraz żądania zasobów podrzędnych. Najbardziej przydatnym dla kontroli osadzania jest Sec-Fetch-Dest — informuje on serwer, w jakim kontekście żądano zasób, bez potrzeby jakiejkolwiek współpracy ze strony inicjującej żądanie.
- Sec-Fetch-Dest: document — nawigacja najwyższego poziomu, nie wewnątrz żadnej ramki.
- Sec-Fetch-Dest: iframe — żądanie jest ładowane wewnątrz elementu <iframe>.
- Sec-Fetch-Dest: frame — ładowane wewnątrz przestarzałego znacznika <frame> (frameset).
- Sec-Fetch-Dest: embed / object — ładowane wewnątrz elementu <embed> lub <object>.
Narzędzie sprawdzające (checker) wysyła własne żądanie sondujące z nagłówkiem Sec-Fetch-Dest: iframe, idealnie odwzorowując to, co wysyła prawdziwa przeglądarka podczas osadzania strony — dzięki temu werdykt odzwierciedla rzeczywistą reakcję docelowego serwera na autentyczne żądania iframe, a nie tylko na standardowe pobieranie danych.
Nagłówek Sec-Fetch-Dest to użyteczny sygnał, ale nie stanowi samodzielnej granicy bezpieczeństwa: generują go wyłącznie nowoczesne przeglądarki, a klienci inni niż przeglądarki — takie jak curl, boty, niektóre komponenty Webview czy starsze przeglądarki — mogą go zupełnie pominąć lub przekazać dowolną wartość. Serwer może go logować lub stosować do ograniczania częstości żądań (rate limiting), lecz nigdy nie powinien opierać wyłącznie na nim decyzji o bezpiecznym osadzaniu w ramce. Odpowiedzialność za tę decyzję należy bowiem do dyrektyw X-Frame-Options oraz frame-ancestors w CSP, które przeglądarki egzekwują niezależnie od nagłówków przesyłanych w żądaniu.
Po stronie klienta dokument może również wykryć, że działa wewnątrz ramki, bez konieczności polegania na nagłówkach — na przykład poprzez sprawdzenie warunku window.top !== window.self (lub odczytanie właściwości window.frameElement dla ramek pochodzących z tej samej domeny). Następnie może zareagować stosownie: wyświetlić ostrzeżenie lub wymusić przejście do okna nadrzędnego (top-level redirect). Opisano tę technikę jako frame-busting, która działa niezawodnie, niezależnie od zawartości nagłówków żądania.
Przykładowe konfiguracje serwerów: blokowanie osadzania w iframe
Poniższe przykłady kodu prezentują metodę konfiguracji każdego serwera lub frameworka w celu całkowitego zablokowania osadzania w iframach (X-Frame-Options: DENY + CSP frame-ancestors 'none') — stanowi to najbardziej restrykcyjną opcję spośród zaprezentowanych w przewodniku ekspresowym powyżej.
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 });
},
};
Wystarczy zezwolić wyłącznie własnej witrynie lub krótkiej białej liście na osadzanie, zamiast blokować wszystkich? Zamień DENY na SAMEORIGIN oraz 'none' na 'self' lub jawną listę adresów — reszta konfiguracji pozostaje bez zmian.
Znane ograniczenia i uwagi dotyczące platform
Pomijając ogólne zasady dotyczące nagłówków, znane platformy często mają swoje specyficzne uwarunkowania. Warto je mieć na uwadze, zanim uznasz daną stronę za „zablokowaną” lub „nadającą się do osadzenia” wyłącznie na podstawie analizy nagłówków.
| Platforma \/ scenariusz | Zachowanie | Uzasadnienie |
|---|---|---|
| Strona oglądania na YouTube (youtube.com\/watch) | Zablokowana | Użyj oficjalnego adresu URL odtwarzacza youtube.com\/embed\/{id} — zwykła strona do oglądania wysyła rygorystyczną politykę osadzania. |
| Strona miejsca na Google Maps | Zablokowana | Tylko adres URL iframe z interfejsu Maps Embed API (google.com\/maps\/embed) został zaprojektowany do osadzania w ramce. |
| Strony logowania OAuth Google \/ Microsoft | Zablokowana | Celowo zablokowana od 2015 roku w celu przeciwdziałania phishingowi wykradającemu dane logowania w ramach iframe'ów; proces logowania musi przebiegać w oknie nadrzędnym lub wyskakującym. |
| Strony dokonywania płatności (Stripe Checkout, PayPal, większość bramek bankowych) | Zablokowana | Osadzenie formularza płatności to klasyczny atak typu clickjacking, dlatego procesory płatnicze odrzucają go wprost. |
| Strony repozytoriów \/ plików na GitHubie | Zablokowana | W całym serwisie ustawiona dyrektywa frame-ancestors 'none'; zamiast iframe skorzystaj z interfejsów REST\/GraphQL lub wykorzystaj zrzuty ekranu. |
| Strony „Opublikuj w internecie” w Notion \/ Google Docs | Do osadzenia | Zaprojektowane wyraźnie pod kątem osadzania, a produkt dostarcza gotowy kod do osadzania. |
| Artykuły z Wikipedii | Do osadzenia | Domyślnie brakuje restrykcyjnych nagłówków X-Frame-Options\/CSP, ale przed osadzaniem masowym sprawdź warunki licencyjne i wymagania dotyczące przypisania autorstwa. |
Typowe przypadki użycia
- Określ, czy zewnętrzny widżet, dashboard lub dokument może zostać osadzony we własnym produkcie, zanim zaczniesz programować integrację.
- Zweryfikuj, czy Twoja witryna poprawnie zwraca oczekiwaną politykę X-Frame-Options lub frame-ancestors w nagłówku CSP.
- Debuguj ochronę przed clickjackiem: sprawdź, dlaczego strona wyświetla `about:blank` lub komunikat o odrzuceniu wewnątrz ramki iframe.
- Weryfikuj adresy URL grupowo podczas agregacji treści lub integracji portali, wykorzystując historię sesji do ponownego przeglądania wyników.
- Przygotuj się do przeglądów bezpieczeństwa lub testów penetracyjnych, dokumentując politykę osadzania w ramkach zewnętrznych zależności.