iframe-insluitingscontrole

Gratis online iframe-checker: voer een willekeurige pagina-URL in om de X-Frame-Options- en Content-Security-Policy frame-ancestors-headers te inspecteren, bekijk of de pagina in een iframe kan worden ingebed en bevestig dit met een live voorbeeld. De geschiedenis wordt bewaard gedurende de huidige browsersessie.

IFrame-embedcontrole

:

Verwerkt elke regel via dezelfde headercontrole en voegt deze toe aan de sessiegeschiedenis hieronder. Maximaal 20 URLs per batch, gelijktijdig enkele om de doelservers niet te overbelasten.

Verwerkt: /
URL Resultaat HTTP

Live voorbeeld

Headerinspectie is een snelle eerste scan, maar kan JavaScript frame-busting niet detecteren: als de headers 'In te bedden' rapporteren maar het voorbeeld leeg blijft, naar buiten breekt of een foutpagina toont, dan is de pagina niet veilig in te bedden. Het live voorbeeld biedt het definitieve antwoord.

Geschiedenis (deze sessie)

Alleen opgeslagen in dit tabblad (sessionStorage); wordt verwijderd bij het sluiten van het tabblad. Er wordt geen data naar de server verstuurd.

Nog geen controles uitgevoerd in deze sessie.

Hoe de controle werkt

  1. Voer de doel-URL in en klik op Controleren. De server haalt de pagina op als een standaard iframe-verzoek (met Sec-Fetch-Dest: iframe) en analyseert de responsheaders.
  2. Het eindoordeel wordt bepaald door X-Frame-Options (DENY/SAMEORIGIN blokkeert framers) en Content-Security-Policy frame-ancestors (alleen * of een schema-wildcard staat willekeurige derden toe als ouder-element).
  3. Dezelfde URL wordt geladen in het live-preview iframe, zodat je kunt bekijken hoe de browser hiermee omgaat, inclusief JavaScript frame-busting die niet zichtbaar is in de headers.

Wat bepaalt of een pagina kan worden ingebed?

Of een webpagina in een <iframe> op een andere site getoond mag worden, beslist de browser aan de hand van de antwoordheaders die de pagina zelf retourneert. Deze scanner voert exact dezelfde inspectie server-side uit en geeft je direct uitsluitsel.

X-Frame-Options is de klassieke header: DENY verbiedt framing op alle pagina's, SAMEORIGIN staat alleen pagina's van dezelfde oorsprong toe om hem te omvatten, en ALLOW-FROM is uit moderne browsers geschrapt. Wanneer deze header ontbreekt, blokkeren verouderde regels de framing niet.

Content-Security-Policy frame-ancestors is de moderne vervanger. Het specificeert welke oorsprongen de pagina mogen insluiten — bijvoorbeeld frame-ancestors 'self' https://example.com. Een waarde van * (of enkel een protocol zoals https:) staat insluiting via elke HTTPS-containerpagina toe; elk restrictiever beleid blokkeert insluiting door derden.

Headers vertellen niet het gehele verhaal: scripts op de pagina kunnen anti-framebusting-code uitvoeren (door `top !== self` te vergelijken en te forceren dat er naar de hoofdpagina wordt genavigeerd), en inlogpagina's of geo-beperkte eindpunten kunnen anders reageren op verzoeken vanuit datacenters. Daarom wordt elk resultaat gekoppeld aan een live-voorbeeld.

Snelle gids: configuratie van responsheaders

Als je eigenaar van de site bent, beheer de framing direct via antwoordheaders.

Insluiting vanuit elke pagina blokkeren

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

Browsers weigeren de pagina weer te geven in een iframe — dit biedt de strengste clickjacking-bescherming.

Alleen insluiting vanaf dezelfde oorsprong toestaan

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

Alleen pagina's met hetzelfde protocol, host en poort mogen deze omvatten; externe websites worden geblokkeerd.

Alleen insluiting vanaf specifieke oorsprongen toestaan

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

Vermeld vertrouwde oorsprongen in frame-ancestors; niet-opgenomen oorsprongen worden geblokkeerd.

Insluiting vanuit elke pagina toestaan

X-Frame-Options niet instellen Content-Security-Policy: frame-ancestors *

Elke site kan de pagina in een iframe tonen. Evalueer de veiligheidsafweging hierbij zorgvuldig.

Opmerking: X-Frame-Options wordt vervangen door CSP frame-ancestors. Indien beide aanwezig zijn, heeft CSP voorrang — geef de voorkeur aan frame-ancestors.

Hoe detecteert de server dat een verzoek vanuit een iframe komt?

Sinds circa 2020 koppelen browsers op basis van Chromium en Firefox automatisch een set Fetch Metadata-verzoekheaders aan elke navigatie- en subresource-aanvraag. De meest nuttige hiervoor bij framingscontroles is Sec-Fetch-Dest — deze informeert de server in welke context het bronbestand werd opgevraagd, zonder dat de aanvragende pagina daar actief mee hoeft samen te werken.

  • Sec-Fetch-Dest: document — navigatie op toppagina-niveau, niet binnen een frame.
  • Sec-Fetch-Dest: iframe — het verzoek wordt geladen binnen een <iframe>-element.
  • Sec-Fetch-Dest: frame — geladen binnen een verouderd <frame>-element (frameset).
  • Sec-Fetch-Dest: embed / object — geladen binnen een <embed>- of <object>-element.

Deze tester stuurt een eigen probe met `Sec-Fetch-Dest: iframe`, exact zoals een echte browser dat doet bij het inbedden van een pagina. Het oordeel weerspiegelt daarom hoe de doelserver daadwerkelijk reageert op echte iframe-verzoeken, in plaats van alleen op een algemene fetch.

`Sec-Fetch-Dest` is een nuttig signaal, maar vormt geen beveiligingslimiet: deze wordt uitsluitend door moderne browsers verzonden. Clients buiten de browser — zoals cURL, bots, bepaalde webviews en oudere browsers — kunnen deze helemaal weglaten of een willekeurige waarde versturen. Een server kan hierop loggen of throttlen, maar mag er nooit uitsluitend op vertrouwen om te bepalen of het inbedden veilig is. De uiteindelijke beslissing ligt bij `X-Frame-Options` en `CSP frame-ancestors`, die browsers afdwingen ongeacht de verzoekheaders.

Aan de kliantzijde kan een pagina ook detecteren dat deze in een frame draait, zelfs zonder specifieke headers. Dit gaat bijvoorbeeld door `window.top !== window.self` te controleren (of `window.frameElement` uit te lezen bij same-origin frames), waarna gereageerd kan worden — door een waarschuwing te tonen of een redirect naar de hoofdweergave af te dwingen. Dit is de eerder genoemde 'frame-busting'-techniek, die werkt ongeacht de inhoud van de verzoekheaders.

Voorbeelden van serverconfiguratie: iframe-inbedden blokkeren

De onderstaande fragmenten laten zien hoe je elke server of framework configureert om iframe-insluiting volledig te blokkeren (X-Frame-Options: DENY + CSP frame-ancestors 'none') — de strengste variant uit de recepten uit de snelle gids hierboven.

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 });
  },
};

Wil je alleen je eigen site, of een korte whitelist, toestaan om de pagina te omvatten in plaats van iedereen te blokkeren? Vervang DENY door SAMEORIGIN, en 'none' door 'self' of een expliciete lijst van oorsprongen — de overige configuratie blijft onveranderd.

Bekende valkuilen per platform

Los van de algemene headerregels hanteren sommige bekende platforms eigen specifieke gedragingen. Het is goed om dit te weten voordat je puur op basis van headers beslist of iets 'geblokkeerd' of 'inbedbaar' is.

Platform / scenario Gedrag Waarom
YouTube-watchpagina (youtube.com/watch) Geblokkeerd Gebruik in plaats daarvan de officiële `youtube.com/embed/{id}`-speler-URL. De standaard kijkpagina hanteert namelijk een restrictief frameringbeleid.
Google Maps-locatiepagina Geblokkeerd Alleen de iframe-URL van de Maps Embed API (`google.com/maps/embed`) is specifiek ontworpen om ingebed te worden.
OAuth-inlogpagina's van Google / Microsoft Geblokkeerd Bewust geblokkeerd sinds 2015 om phishing van inloggegevens via iframes te voorkomen. Het inlogproces moet altijd in een hoofdscherm of pop-upvenster plaatsvinden.
Betaal- en afhandelingspagina's (Stripe Checkout, PayPal, de meeste bankportalen) Geblokkeerd Het invoegen van betaalformulieren in een frame is een klassiek clickjacking-middeltje, waardoor betalingsverwerkers dit standaard blokkeren.
GitHub-repository- en bestandspagina's Geblokkeerd De instelling voor `frame-ancestors` geldt sitebreed als 'none'. Gebruik liever de REST- of GraphQL-API of maak gebruik van een screenshot.
Notion- en Google Docs-pagina's ('Publiceren op internet') Inbedbaar Deze zijn expliciet ontworpen om ingebed te worden en bieden kant-en-klare inbedcodes aan.
Wikipedia-artikelen Inbedbaar Standaard zijn er geen restrictieve `X-Frame-Options` of CSP-instellingen, maar controleer wel de licentie- en creditvoorwaarden voordat je ze massaal wilt inbedden.

Veelvoorkomende toepassingen

  • Bepaal eerst of widgets, dashboards of documenten van derden in jouw product ingebed kunnen worden voordat je code voor de integratie gaat schrijven.
  • Verifieer of jouw eigen website correct de beoogde `X-Frame-Options`- of CSP `frame-ancestors`-policy verstuurt.
  • Debug clickjacking-bescherming: begrijp waarom een pagina binnen een iframe over about:blank of een weigermelding wordt weergegeven.
  • Controleer kandidaat-URLs batchsgewijs tijdens inhoudsamenvoeging of portaalintegratie, waarbij je de sessiegeschiedenis gebruikt om resultaten opnieuw te bekijken.
  • Bereid je voor op beveiligingsreviews of penetration tests door het frameerbeleid van externe afhankelijkheden te documenteren.

Veelgestelde vragen

Waarom blijft een pagina die als \"Embeddable\" wordt gemarkeerd, leeg in het voorbeeld?
De antwoordheaders staan frameerbieding toe, maar de pagina bevat waarschijnlijk JavaScript frame-busting, vereist aanmelding of cookies, of toont andere inhoud afhankelijk van de bezoeker. Vertrouw het voorbeeld.
Kan ik X-Frame-Options of CSP omzeilen?
Nee. Deze headers worden door de browser afgedwongen voor beveiliging (preventie van clickjacking); client-side oplossingen zijn onbetrouwbaar. Om content in te sluiten die niet onder jouw beheer valt, vraag de site-eigenaar dan jouw origin toe te laten tot de allowlist in frame-ancestors, of gebruik een officiële embed-/API-oplossing die zij aanbieden.
Wat is het verschil tussen DENY en SAMEORIGIN?
DENY blokkeert de pagina in elk iframe, inclusief pagina's van dezelfde oorsprong; SAMEORIGIN staat frameerbieding alleen toe door pagina's van hetzelfde protocol, host en poort.
Slaat de checker mijn URL's op?
Geschiedenis blijft uitsluitend in jouw eigen browsertab via sessionStorage en vervalt zodra de tab wordt gesloten. De checker haalt alleen de opgevraagde URL op om de antwoordheaders te lezen.
Waarom geeft dezelfde URL op verschillende momenten verschillende resultaten?
Websites kunnen verschillende headers sturen per pad, na omleidingen, op basis van User-Agent, of afhankelijk van A/B-tests en WAF-regels. Voer de controle opnieuw uit om de huidige status op te halen.