02 - Manifest V3 Security and Permissions
Migrating from Manifest V2 to V3: Security Benefits
MV3 introduces several major security enhancements over MV2:
- No remote code execution:
eval()and fetching remote JavaScript are banned. All code must be bundled within the extension. - Service Workers: Replacing persistent background pages limits long-running malicious processes.
- Declarative Net Request: Replaces
webRequestblocking API, preventing extensions from observing all user network traffic just to block ads.
Content Security Policy (CSP) in Extensions
MV3 enforces a strict, unmodifiable CSP for extension pages and service workers.
Default MV3 CSP: script-src 'self'; object-src 'self';
You cannot loosen this to allow unsafe-eval or remote scripts.
The Principle of Least Privilege: Permissions
Vulnerable Pattern: <all_urls>
Requesting <all_urls> means the extension can read/modify data on every single site.
{
"manifest_version": 3,
"name": "Vulnerable Extension",
"version": "1.0",
"permissions": ["storage"],
"host_permissions": ["<all_urls>"] // DANGEROUS
}
Secure Pattern: activeTab
Use activeTab to only gain access when the user explicitly interacts with the extension (e.g., clicking the extension icon).
{
"manifest_version": 3,
"name": "Secure Extension",
"version": "1.0",
"permissions": ["activeTab", "storage"]
}
declarativeNetRequest
Instead of intercepting every request (which requires broad host permissions and exposes user data), you define rules for the browser to evaluate.
// rules.json
[
{
"id": 1,
"priority": 1,
"action": { "type": "block" },
"condition": { "urlFilter": "||malicious-tracker.com", "resourceTypes": ["script"] }
}
]
// manifest.json
{
"permissions": ["declarativeNetRequest"],
"declarative_net_request": {
"rule_resources": [{
"id": "ruleset_1",
"enabled": true,
"path": "rules.json"
}]
}
}