Verifica incorporamento iframe
Verificatore iframe online gratuito: inserisci l'URL di una pagina web per ispezionarne le intestazioni X-Frame-Options e Content-Security-Policy frame-ancestors, scopri se la pagina può essere integrata in un iframe e conferma con un'anteprima live. La cronologia viene mantenuta solo durante la sessione corrente del browser.
Cronologia (questa sessione)
Salvata solo in questa scheda (sessionStorage); eliminata alla chiusura della scheda. Nessun dato viene inviato al server.
Come funziona la verifica
- Inserisci l'URL di destinazione e clicca Verifica. Il server recupera la pagina simulando una richiesta iframe reale (con Sec-Fetch-Dest: iframe) e ne legge le intestazioni di risposta.
- Il verdetto dipende da X-Frame-Options (DENY/SAMEORIGIN bloccano l'inserimento) e Content-Security-Policy frame-ancestors (solo * o un segnaposto di protocollo permettono origini di terze parti arbitrarie).
- Lo stesso URL viene caricato nell'iframe dell'anteprima live per consentirti di confermare il comportamento effettivo del browser, incluso il codice JavaScript frame-busting non rilevabile dalle sole intestazioni.
Cosa determina se una pagina può essere integrata?
Se una pagina web possa essere visualizzata all'interno di un <iframe> su un altro sito viene deciso dal browser, in base agli header di risposta inviati dalla pagina stessa. Questo strumento esegue la medesima verifica lato server e ti restituisce un verdetto immediato.
X-Frame-Options è l'header classico: DENY vieta l'inserimento in frame per qualsiasi pagina, SAMEORIGIN consente solo alle pagine della stessa origine di includerla in un frame, mentre ALLOW-FROM è stato rimosso dai browser moderni. Quando l'header è assente, le regole legacy non bloccano l'inserimento in frame.
Content-Security-Policy frame-ancestors è il successore moderno. Indica quali origini sono autorizzate a incorporare la pagina — ad esempio `frame-ancestors 'self' https://example.com`. Un valore * (o un semplice schema come https:) permette qualsiasi frame HTTPS padre; qualsiasi filtro più restrittivo blocca l'incorporamento da terze parti.
Gli header non raccontano tutta la storia: gli script di pagina possono eseguire codice anti-clickjacking (confrontando `top !== self` e forzando una navigazione di primo livello), e le pagine di accesso o gli endpoint con restrizioni geografiche potrebbero rispondere diversamente alle richieste provenienti da data center. Ecco perché ogni risultato è acompañado da un'anteprima live.
Guida rapida: configurazione delle intestazioni di risposta
Se possiedi il sito, gestisci direttamente l'inserimento in frame tramite gli header di risposta.
Blocca l'inserimento da qualsiasi pagina
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
I browser rifiutano di visualizzare la pagina all'interno di qualsiasi iframe: è la massima protezione contro il clickjacking.
Consenti inserimento solo dalla stessa origine
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
Solo le pagine con lo stesso protocollo, host e porta possono includerlo in un frame; i siti di terze parti sono bloccati.
Consenti inserimento solo da origini specifiche
Content-Security-Policy: frame-ancestors 'self' https://trusted.example.com
Elenca le origini attendibili in frame-ancestors; le origini non elencate saranno bloccate.
Consenti inserimento da qualsiasi pagina
Non impostare X-Frame-Options
Content-Security-Policy: frame-ancestors *
Qualsiasi sito può inserire la pagina in un iframe. Valuta attentamente i rischi per la sicurezza.
Nota: X-Frame-Options è stato superato da frame-ancestors nella CSP. Quando sono presenti entrambi, prevale la CSP: preferisci frame-ancestors.
Come rileva il server che una richiesta proviene da un iframe?
A partire dal 2020 circa, i browser basati su Chromium e Firefox aggiungono automaticamente una serie di header Fetch Metadata a ogni richiesta di navigazione e di sotto-risorsa. Il più utile per i controlli sui frame è Sec-Fetch-Dest: informa il server sul tipo di contesto che richiede la risorsa, senza che la pagina richiedente debba fornire alcun dato aggiuntivo.
- Sec-Fetch-Dest: document — navigazione di primo livello, non all'interno di alcun frame.
- Sec-Fetch-Dest: iframe — la richiesta viene caricata all'interno di un elemento <iframe>.
- Sec-Fetch-Dest: frame — caricato all'interno di un vecchio <frame> (frameset).
- Sec-Fetch-Dest: embed / object — caricato all'interno di un elemento <embed> o <object>.
Questo verificatore invia una propria sonda con Sec-Fetch-Dest: iframe, replicando esattamente ciò che invia un browser reale quando incorpora una pagina — così l'esito riflette come il server di destinazione si comporti realmente per richieste iframe genuine, e non per una generica richiesta HTTP.
Sec-Fetch-Dest è un segnale utile ma non costituisce una barriera di sicurezza: viene inviato solo dai browser moderni, mentre client non browser — curl, bot, alcune WebView e browser datati — possono ometterlo del tutto o inviare un valore arbitrario. Un server può registrarne l'uso o applicare il rate limiting, ma non dovrebbe mai affidarsi esclusivamente a questo header per decidere se l'inserimento in un frame è sicuro; tale controllo spetta comunque a X-Frame-Options e CSP frame-ancestors, che i browser applicano indipendentemente dagli header della richiesta.
Dal lato client, una pagina può anche rilevare di essere all'interno di un frame senza dipendere da alcun header, ad esempio confrontando window.top !== window.self (oppure leggendo window.frameElement per frame allo stesso origine), per poi reagire — mostrando un avviso o forzando un redirect alla finestra principale. Si tratta della tecnica frame-busting accennata in precedenza, efficace indipendentemente dal contenuto degli header della richiesta.
Esempi di configurazione server: blocco integrazione iframe
Gli snippet seguenti mostrano come configurare ciascun server o framework per bloccare completamente l'inserimento negli iframe (X-Frame-Options: DENY + CSP frame-ancestors 'none'), ovvero l'impostazione più rigorosa indicata nella guida rapida precedente.
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 });
},
};
Dev'essere consentito solo al tuo sito o a una breve lista bianca di inserire la pagina in un frame, invece di bloccare tutti? Sostituisci DENY con SAMEORIGIN, e 'none' con 'self' o un elenco esplicito di origini: il resto della configurazione rimane invariato.
Note e avvertenze note sulle piattaforme
Fatti salve le regole generali sugli header, alcune piattaforme affermate presentano proprie peculiarità — un dettaglio da conoscere prima di dedurre che una risorsa sia \"bloccata\" o \"integrabile\" basandosi esclusivamente sugli header.
| Piattaforma \/ scenario | Comportamento | Spiegazione |
|---|---|---|
| Pagina di visualizzazione YouTube (youtube.com\/watch) | Bloccato | Utilizza invece l'URL ufficiale youtube.com\/embed\/ {id} per il player — la normale pagina di visualizzazione trasmette una politica di framing restrittiva. |
| Pagina luogo Google Maps | Bloccato | Solo l'URL dell'iframe della Maps Embed API (google.com\/maps\/embed) è progettato per essere inserito in un frame. |
| Pagine di accesso OAuth Google \/ Microsoft | Bloccato | Intenzionalmente bloccato dal 2015 per prevenire phishing di credenziali all'interno di iframe; il flusso di accesso deve avvenire in una finestra principale o in un popup. |
| Pagine di checkout dei pagamenti (Stripe Checkout, PayPal, la maggior parte dei gateway bancari) | Bloccato | Inserire un modulo di pagamento in un frame è un vettore classico di clickjacking, motivo per cui i processori di pagamento lo rifiutano esplicitamente. |
| Pagine di repository \/ file GitHub | Bloccato | Policy site-wide frame-ancestors impostata su 'none'; utilizza l'API REST\/GraphQL o uno screenshot al posto di un iframe. |
| Pagine Notion \/ Google Docs \"Pubblica sul web\" | Integrabile | Progettate esplicitamente per l'integrazione; il prodotto fornisce inoltre un codice di incorporamento già pronto. |
| Articoli Wikipedia | Integrabile | Non prevede policy X-Frame-Options\/CSP restrittive di default, ma verifica sempre i termini di licenza e attribuzione prima di effettuare integrazioni su larga scala. |
Casi d'uso comuni
- Valuta se un widget, una dashboard o un documento di terze parti possa essere integrato nel tuo prodotto prima di sviluppare il codice di integrazione.
- Verifica che il tuo sito invii effettivamente la policy X-Frame-Options o CSP frame-ancestors da te impostata.
- Debug della protezione anti-clickjacking: comprendi perché una pagina visualizza `about:blank` o un messaggio di diniego all'interno di un iframe.
- Verifica in batch gli URL candidati durante l'aggregazione dei contenuti o l'integrazione di portali, sfruttando la cronologia delle sessioni per riesaminare i risultati.
- Preparati alle verifiche di sicurezza o ai penetration test documentando la politica di framing delle dipendenze esterne.