Kontrola vkládání iframe
Bezplatná online kontrola IFrame: zadejte URL jakékoli webové stránky a zkontrolujte její hlavičky X-Frame-Options a Content-Security-Policy frame-ancestors. Zjistěte, zda lze stránku vložit do IFrame, a potvrďte výsledek živým náhledem. Historie se ukládá pouze pro aktuální relaci prohlížeče.
Historie (tato relace)
Uloženo pouze v této kartě (sessionStorage); při jejím zavření vymazáno. Nic se neposílá na server.
Jak kontrola funguje
- Zadejte cílovou adresu URL a klikněte na Zkontrolovat. Server stáhne stránku jako skutečný požadavek IFrame (s hlavičkou Sec-Fetch-Dest: iframe) a přečte její odpovědní hlavičky.
- Výsledek je určen hlavičkou X-Frame-Options (hodnoty DENY / SAMEORIGIN rámování blokují) a Content-Security-Policy frame-ancestors (pouze * nebo zástupný znak schématu povolují libovolné rodičovské domény třetích stran).
- Stejná adresa URL se načte v náhledovém IFrame, abyste si mohli ověřit, co prohlížeč ve skutečnosti provede, včetně JavaScriptových obran proti vložení, které hlavičky neodhalí.
Co určuje, zda lze stránku vložit?
Zda lze webovou stránku zobrazovat uvnitř `<iframe>` na jiném webu, rozhoduje prohlížeč na základě odpovědních HTTP hlaviček, které tato stránka posílá. Tento nástroj provádí stejnou inspekci na straně serveru a poskytuje vám okamžitý výsledek.
`X-Frame-Options` je klasická hlavička: hodnota `DENY` zakazuje obalování rámcem na jakékoli stránce, `SAMEORIGIN` povoluje pouze stránkám ze stejného původu, `ALLOW-FROM` byla v moderních prohlížečích odstraněna. Při její absenci není vkládání do rámců žádnými staršími pravidly blokováno.
Moderní náhradou je direktiva CSP `frame-ancestors`. Uvádí v ní seznam originů, které mají oprávnění stránku vložit do svého rámu – například `frame-ancestors 'self' https://example.com`. Hodnota `*` (nebo pouhé schéma např. `https:`) připouští jakéhokoli nadřazeného kontextu HTTPS; cokoliv přísnějšího pak blokuje vkládání z externích domén.
Hlavičky však neposkytují kompletní obrázek: webové skripty mohou vykonávat tzv. frame-busting kód (porovnávají `top !== self` a vynucují přesměrování na nejvyšší úrovni) a přihlašovací stránky nebo geograficky omezené endpointy mohou reagovat odlišně při požadavcích pocházejících z cloudových datových center. Právě proto je ke každému výsledku přiložen i živý náhled.
Rychlý průvodce: nastavení odpovědních hlaviček
Pokud vlastníte web, můžete možnost vkládání do rámců řídit přímo pomocí odpovědních hlaviček.
Blokovat vkládání ze všech zdrojů
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
Prohlížeče odmítnou vykreslit stránku v jakémkoli `<iframe>` — jedná se o nejpřísnější ochranu proti clickjackingu.
Povolit vkládání pouze ze zdrojů téhož původu
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
Vkládat mohou pouze stránky se stejným schématem, hostitelem a portem; weby třetích stran jsou blokovány.
Povolit vkládání pouze z vybraných zdrojů
Content-Security-Policy: frame-ancestors 'self' https://trusted.example.com
Do direktivy `frame-ancestors` uveďte seznam důvěryhodných originů; ty, které nejsou uvedeny, budou blokovány.
Povolit vkládání ze všech zdrojů
Nepoužívejte hlavičku X-Frame-Options
Content-Security-Policy: frame-ancestors *
Libovolný web může tuto stránku vložit do `<iframe>`. Důkladně zhodnoťte bezpečnostní rizika a kompromisy.
Poznámka: Hlavička `X-Frame-Options` je nahrazena direktivou CSP `frame-ancestors`. Při současném použití má vždy prioritu CSP — doporučujeme spoléhat primárně na `frame-ancestors`.
Jak server detekuje, že požadavek pochází z IFrame?
Od roku 2020 přidávají prohlížeče založené na Chromiu a Firefofu automaticky k jakékoli navigaci a požadavkům na podzdroje sadu meta-hlaviček Fetch Metadata. Pro účely kontroly vkládání do rámců je klíčový parametr `Sec-Fetch-Dest` – informuje server o kontextu, ve kterém byl zdroj požadován, aniž by k tomu bylo zapotřebí spolupráce cílové stránky.
- `Sec-Fetch-Dest: document` — navigace nejvyšší úrovně (neprobíhá uvnitř žádného rámu).
- `Sec-Fetch-Dest: iframe` – požadavek byl načten uvnitř elementu `<iframe>`.
- `Sec-Fetch-Dest: frame` – načteno uvnitř historického elementu `<frame>` (frameset).
- `Sec-Fetch-Dest: embed / object` – načteno uvnitř elementů `<embed>` nebo `<object>`.
Tento tester odesílá vlastní sondovací dotaz s hlavičkou `Sec-Fetch-Dest: iframe`, který přesně kopíruje, co skutečný prohlížeč pošle při vkládání stránky. Výsledek tedy odráží, jak se cílový server reálně chová vůči legitimním iframe requestům, nikoliv pouze k běžnému stahování dat.
`Sec-Fetch-Dest` je užitečný signál, ale nepředstavuje bezpečnostní hranici: generují jej pouze moderní prohlížeče. Klienti mimo prohlížeč — např. `curl`, boti, některé webview komponenty či starší prohlížeče — ji mohou zcela vynechat nebo poslat libovolnou hodnotu. Server by ji měl využívat primárně pro protokolování nebo rate-limiting, ale nikdy by se neměl spolehnout pouze na ni pro rozhodování o bezpečnosti vnoření. O tuto bezpečnostní politiku musí jednat `X-Frame-Options` a `CSP frame-ancestors`, které prohlížeče vynucují nezávisle na obsahu hlaviček požadavku.
Na straně klienta může stránka také detekovat, že běží uvnitř rámečku, a to bez použití jakýchkoli hlaviček – například porovnáním `window.top !== window.self` (nebo čtením `window.frameElement` pro rámce stejného původu), a následně adekvátně zareagovat: zobrazit varování nebo vynutit přesměrování do nadřazeného okna. Jde o zmiňovanou techniku frame-busting, která funguje bez ohledu na to, jaké hlavičky byly v původním požadavku.
Příklady konfigurace serveru: blokování vnoření do IFrame
Následující ukázky kódu ukazují, jak nakonfigurovat daný server nebo framework tak, aby kompletně zablokoval vkládání do `<iframe>` (kombinace `X-Frame-Options: DENY` a `CSP frame-ancestors 'none'`). Jde o nejpřísnější řešení z rychlého průvodce výše.
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 });
},
};
Stačí povolit pouze vlastní web nebo krátký whitelist pro vkládání místo úplného blokování všech zdrojů? Nahraďte hodnotu `DENY` za `SAMEORIGIN` a `'none'` za `'self'` či explicitní seznam originů – zbývající část konfigurace zůstává beze změny.
Pozor na typické problémy platforem
Kromě obecných pravidel pro hlavičky mají některé známé platformy svá specifika – stojí za to je znát, než budete z pouhého pohledu na hlavičky usuzovat, že je obsah ‚blokován‘, nebo zda jej lze ‚vložit‘.
| Platforma / scénář | Chování | Důvod |
|---|---|---|
| Stránka pro sledování videí YouTube (youtube.com/watch) | Blokováno | Místo toho použijte oficiální URL přehrávače `youtube.com/embed/{id}` — běžná stránka pro sledování videí odesílá restriktivní politiku vnořování. |
| Stránka místa Google Maps | Blokováno | Pro vnoření je určená pouze adresa iframe rozhraní Maps Embed API (google.com/maps/embed). |
| Přihlašovací stránky OAuth Google / Microsoft | Blokováno | Účelově blokováno od roku 2015 k zastavení phishingu přihlašovacích údajů v rámci iframe; proces přihlášení musí proběhnout v hlavním okně nebo jako vyskakovací dialog. |
| Platební pokladny (Stripe Checkout, PayPal, většina bankovních bran) | Blokováno | Je vnoření platebního formuláře klasickou cestou pro provedení clickjackingu, takže platobní procesory mu přímo odmítají vyhovět. |
| Stránky repozitářů / souborů GitHubu | Blokováno | Globální direktiva `frame-ancestors none`; místo iframe použijte REST/GraphQL API nebo pořiďte snímek obrazovky. |
| Funkce „Zveřejnit na webu“ v aplikacích Notion / Google Docs | Lze vložit | Jsou výslovně navrženy pro embeddování a produkt poskytuje připravený kód pro vložení. |
| Články na Wikipedii | Lze vložit | Ve výchozím nastavení neobsahují restriktivní `X-Frame-Options` ani CSP, před rozsáhlým vkládáním si však ověřte licenční podmínky a pravidla citace autorů. |
Běžné scénáře použití
- Rozhodněte se, zda můžete widget, dashboard nebo dokument třetí strany vložit do svého vlastního produktu ještě před tím, než začnete implementovat integraci.
- Ověřte, že váš vlastní web skutečně vysílá zamýšlenou politiku `X-Frame-Options` nebo `CSP frame-ancestors`.
- Ladění ochrany proti clickjacku: zjistěte, proč se stránka uvnitř iframe zobrazuje prázdně (`about:blank`) nebo s odmítající zprávou.
- Dávková kontrola kandidátských URL adres při agregaci obsahu nebo integraci portálu; výsledky můžete následně znovu zkontrolovat prostřednictvím historie relace.
- Příprava na bezpečnostní revize nebo penetrační testy pomocí zdokumentování politiky iframe (rámování) externích závislostí.