Firefox Privacy & Security - technical breakdown
01 — Enhanced Tracking Protection
ETP operates at the network request layer inside Firefox's content policy engine. It intercepts resource loads and cross-site navigations before they reach the network, comparing against categorized lists provided by Disconnect.me and processed into a local SQLite database at ~/.mozilla/firefox/[profile]/content-prefs.sqlite.
ETP Modes
| Mode | Blocks | Isolates | Default |
|---|---|---|---|
| Standard | Social trackers, cross-site tracking cookies, fingerprinters, cryptominers | No full first-party isolation | YES |
| Strict | All of Standard + tracking content in all windows | Total cookie protection active | MANUAL |
| Custom | User-defined list categories | Configurable per category | MANUAL |
Total Cookie Protection (TCP)
Enabled by default in Standard mode since Firefox 103. TCP creates a separate cookie jar per top-level origin, implemented in nsICookieManager with origin attributes. Each originAttributes struct carries a firstPartyDomain field; cross-site cookies are namespaced to that field and cannot be read across contexts.
TCP does not block cookies — it partitions them. A tracker can still set cookies and read them within a single first-party context. Combined blocking (Strict mode) is required to prevent tracking across unrelated first parties.
SmartBlock
When Strict mode blocks a tracker that a page depends on for rendering, SmartBlock substitutes a local shim script. As of Firefox 126, shims cover Google Analytics, Facebook Pixel, Google Tag Manager, and several CDN-hosted libraries. Shim code is bundled in the binary and cannot be remotely updated without a browser release.
02 — Network-Level Privacy
DNS over HTTPS
Firefox implements DoH natively via network.trr.* prefs. It operates independently of the OS resolver and uses HTTP/2 POST requests to the configured resolver. Three resolver modes:
// network.trr.mode values:
0 — off (OS resolver only)
1 — race (TRR vs OS, fastest wins)
2 — first (TRR preferred, OS fallback)
3 — TRR only, no OS fallback
5 — off + disables ECS stripping
Mode 3 eliminates DNS leaks entirely but breaks split-horizon DNS and some captive portal detection. Firefox defaults to mode 2 with Cloudflare's resolver (https://mozilla.cloudflare-dns.com/dns-query) in the US, and with NextDNS as an alternative.
Captive portal detection at detectportal.firefox.com makes a plain HTTP request even with DoH enabled. This reveals network presence. Disable via network.captive-portal-service.enabled = false.
OCSP & CRLite
Firefox performs OCSP staple verification by default. Soft-fail is the default behavior: if the OCSP responder is unreachable, the connection proceeds. CRLite, enabled in Firefox 75+, filters revocation status locally from a compressed, periodically updated dataset — eliminating the network round-trip and the privacy implication of OCSP queries leaking visited domains to the CA's OCSP responder.
Set security.OCSP.enabled = 0 and rely on CRLite exclusively for the privacy-optimal configuration. Hard-fail OCSP (security.OCSP.require = true) without CRLite degrades availability without improving security over a soft-fail + CRLite setup.
HTTP/3 & QUIC
Firefox enables HTTP/3 by default. QUIC encrypts connection metadata including stream multiplexing, but the initial handshake still exposes the SNI to passive observers unless ECH (Encrypted Client Hello) is active. ECH is enabled in Firefox 117+ via network.dns.echconfig.enabled = true, but requires server support and a supporting DNS record (HTTPS type).
03 — Fingerprinting Resistance
Firefox's privacy.resistFingerprinting (RFP) pref, inherited from the Tor Browser, applies a suite of spoofing measures targeting the most discriminating fingerprinting vectors.
| API / Surface | RFP Behavior |
|---|---|
| Canvas 2D | Adds per-session noise to getImageData and toDataURL pixel output |
| WebGL | Spoofs renderer and vendor strings; overrides UNMASKED_RENDERER_WEBGL |
| Screen resolution | Reports rounded, common resolution; hides real screen geometry |
| Timezone | Reports UTC regardless of OS timezone setting |
| User-Agent | Reports a fixed, common Windows UA regardless of actual OS |
| Navigator properties | Freezes hardwareConcurrency, deviceMemory, platform |
| Performance API | Reduces timing resolution to 100ms; mitigates timing side-channels |
| Battery API | Disabled entirely |
| AudioContext | Adds noise to audio processing output |
| Font enumeration | Exposes only a curated subset; CSS font-face probing returns fixed metrics |
Tor Browser's RFP is more aggressive — it forces a 1000×1000 window, disables WebGL entirely, and letterboxes content. Vanilla Firefox RFP trades some anti-fingerprinting coverage for usability.
letterboxing
Enabled separately via privacy.resistFingerprinting.letterboxing = true. Adds opaque padding around the content area so the reported inner window dimensions are always a multiple of 200×100px, preventing viewport-based fingerprinting.
FPP (Fingerprinting Protection)
Firefox 119 introduced a modular system (privacy.fingerprintingProtection) that allows individual protections to be toggled granularly via privacy.fingerprintingProtection.overrides, a comma-delimited list of protection identifiers. Protections can be toggled per-site via about:config without enabling full RFP.
04 — Storage Partitioning
Firefox partitions client-side storage by top-level origin. The partition key is stored as part of the origin attributes on all storage primitives: cookies, localStorage, sessionStorage, IndexedDB, Cache API, Service Workers, and SharedWorkers.
State Partitioning vs TCP
Total Cookie Protection covers cookies specifically. State Partitioning (enabled by default in Firefox 86+) extends the same key-based isolation to all storage types. A third-party cdn.example.com embedded in site-a.com and site-b.com sees completely separate storage namespaces in each context.
Service Worker Partitioning
Service Workers are registered with a scope that includes the partition key. A third-party Service Worker cannot share state or intercept requests across top-level origins, eliminating a significant persistent tracking vector that previously allowed indefinite storage via the Cache API even after cookie deletion.
Heuristics & Compatibility Exceptions
Firefox includes automatic heuristics that grant temporary unpartitioned storage access when a redirect flow is detected (e.g., OAuth) or when a popup originates from a user interaction. These heuristics are per-session and time-limited (maximum 30 days). Sites can also request persistent access via the Storage Access API (document.requestStorageAccess()), which requires a user gesture and displays a prompt.
05 — HTTPS & TLS
HTTPS-Only Mode
Enabled via Settings → Privacy & Security → HTTPS-Only Mode. When active, Firefox upgrades all http:// navigations to https:// via an internal redirect before the request leaves the browser. If the upgrade fails (HSTS preload miss + no server HTTPS support), Firefox displays an error page rather than falling through to HTTP. This is distinct from HSTS, which relies on prior server instruction; HTTPS-Only Mode enforces upgrades unconditionally.
TLS Configuration
Minimum TLS version: 1.2 (security.tls.version.min = 3). TLS 1.0 and 1.1 are disabled since Firefox 74 and cannot be re-enabled via about:config without a compile-time change. TLS 1.3 is fully supported including 0-RTT, though 0-RTT is disabled by default due to replay attack exposure (security.tls.enable_0rtt_data = false).
Certificate Transparency
Firefox does not enforce Certificate Transparency (CT) by default, unlike Chrome. Mozilla's policy relies on CA audits and the Mozilla Root Store rather than CT logs. CT checking can be observed but not enforced via extensions. This is a structural difference that means Firefox will not reject certificates missing SCTs.
cert_override.db
Manual certificate exceptions are stored in cert_override.db (SQLite) in the profile directory. Each override encodes the hostname, port, certificate SHA-256 fingerprint, and override flags. Overrides persist across sessions unless explicitly removed.
06 — WebRTC Leak Vectors
WebRTC is the primary privacy failure mode for VPN users. ICE candidate gathering can expose local and public IP addresses via STUN regardless of proxy or VPN configuration, since the WebRTC stack communicates outside the HTTP layer.
Relevant Prefs
// Restrict ICE candidates to default interface only:
media.peerconnection.ice.default_address_only = true
// Block ICE candidates from LAN addresses:
media.peerconnection.ice.no_host = true
// Disable WebRTC entirely (breaks video calls):
media.peerconnection.enabled = false
Setting ice.default_address_only = true is the recommended middle ground: it prevents multi-homed address enumeration while preserving WebRTC functionality. With a VPN active, the exposed address will be the VPN's interface IP rather than the true public IP.
mDNS obfuscation (replacing local IPs with a generated .local hostname) is enabled by default in Firefox on non-Linux platforms. On Linux, media.peerconnection.ice.obfuscate_host_addresses may not function identically due to mDNS stack differences.
07 — Container Tabs
Container tabs are a first-party Firefox feature (not purely an extension mechanism) implemented via contextual identities in the userContextId origin attribute. Each container maps to a unique integer ID; storage, cookies, and cache are fully isolated between containers and from the default (no-container) context.
Container state is stored in containers.json in the profile. The Multi-Account Containers extension from Mozilla adds a UI layer and domain-assignment rules on top of the native API.
Isolation Scope
Container isolation covers: cookies, localStorage, sessionStorage, IndexedDB, Service Workers, HTTP auth credentials, and the HTTP cache. It does not isolate browser history, bookmarks, extensions' IndexedDB, or downloaded files. Tabs within the same container share storage regardless of what site is loaded.
Permanent Private Browsing
Enabling browser.privatebrowsing.autostart = true (via about:config or policies.json) forces all windows into private browsing mode, which clears in-memory storage and cache on close and disables most persistent storage. This is distinct from container isolation: PBM prevents persistence, containers prevent cross-context leakage.
08 — Telemetry Surface Area
Firefox transmits multiple categories of data to Mozilla infrastructure. Understanding what is sent, when, and to which endpoints is prerequisite to meaningful opt-out.
| Category | Endpoint | Opt-Out Method |
|---|---|---|
| Telemetry pings | incoming.telemetry.mozilla.org |
toolkit.telemetry.enabled = false |
| Crash reports | crash-reports.mozilla.com |
Settings → Privacy → Crash Reporter uncheck; breakpad.reportURL = "" |
| Studies / Normandy | normandy.cdn.mozilla.net |
app.shield.optoutstudies.enabled = false |
| Safe Browsing | Google APIs | browser.safebrowsing.*.enabled = false |
| Sponsored suggestions | Contile / AdMarketplace | browser.newtabpage.activity-stream.showSponsoredTopSites = false |
| Firefox Suggest | Merino API | browser.urlbar.quicksuggest.enabled = false |
| Attribution / install ping | data.mozilla.com |
toolkit.telemetry.reportingpolicy.firstRun = false |
Safe Browsing Trade-off
Disabling Safe Browsing removes real-time phishing and malware URL checks, which query Google's servers with URL hashes. The check is hash-prefix based (not full URL), so Google does not receive the exact URL, but the mechanism still involves outbound traffic to Google's infrastructure on every navigation. The privacy cost is low; the security cost of disabling is meaningful.
09 — about:config Hardening
The following prefs are not exposed in the Firefox UI but materially improve the privacy posture. Set via about:config or by placing a user.js file in the Firefox profile directory.
// ── Network ────────────────────────────────────────
network.trr.mode = 3
network.trr.uri = "https://..." // your resolver
network.dns.echconfig.enabled = true
network.captive-portal-service.enabled = false
network.connectivity-service.enabled = false
// ── Fingerprinting ─────────────────────────────────
privacy.resistFingerprinting = true
privacy.resistFingerprinting.letterboxing = true
webgl.disabled = true // optional, breaks WebGL apps
// ── WebRTC ─────────────────────────────────────────
media.peerconnection.ice.default_address_only = true
media.peerconnection.ice.no_host = true
// ── Referrer ───────────────────────────────────────
network.http.referer.XOriginPolicy = 2 // same-origin only
network.http.referer.XOriginTrimmingPolicy = 2 // origin only
// ── Cache ──────────────────────────────────────────
browser.cache.disk.enable = false
browser.sessionstore.privacy_level = 2 // never store senstive form data
// ── Misc ───────────────────────────────────────────
geo.enabled = false
dom.battery.enabled = false
dom.gamepad.enabled = false
device.sensors.enabled = false
beacon.enabled = false
dom.allow_cut_copy = false
clipboard.autocopy = false
Placing a user.js file in the profile directory applies prefs at every startup, overriding any UI changes. It does not persist as a locked policy — prefs can still be changed at runtime but will reset on next launch. For locked enterprise-style deployment use policies.json in the installation directory.
arkenfox user.js
The arkenfox/user.js project maintains a well-documented, regularly updated hardening template covering 400+ prefs with inline rationale. It is the most comprehensive maintained reference for Firefox hardening and explicitly documents trade-offs for each setting.
10 — Extension Ecosystem
Firefox extensions run in a sandboxed process (WebExtensions API) and require explicit permission grants. However, extensions with broad host permissions (<all_urls>) have access to all request and response data, including content of HTTPS-decrypted pages. Extension trust is therefore a critical factor in the overall security posture.
| Extension | Function | Notes |
|---|---|---|
| uBlock Origin | Content blocking via filter lists | Uses declarativeNetRequest + legacy webRequest; supports procedural cosmetic filters. Most comprehensive blocker available. |
| Multi-Account Containers | Container tab management UI | Mozilla-maintained. Exposes contextualIdentities API; stores domain assignments in extension storage. |
| LocalCDN / Decentraleyes | Local CDN resource cache | Intercepts requests to CDN endpoints and serves local copies, eliminating requests to CDN hosts entirely. |
| Canvas Blocker | Canvas API noise injection | Redundant with privacy.resistFingerprinting; useful if RFP is not enabled globally. |
Firefox supports Manifest V3 while retaining the legacy webRequest blocking API, which Chrome removes in MV3. This means uBlock Origin and similar blocking-capable extensions continue to function with full request blocking ability on Firefox, unlike Chromium-based browsers under MV3 where blocking extensions are restricted to the declarativeNetRequest model with limited dynamic rule counts.
Extension Signing
Firefox enforces extension signing by default — extensions must be signed by Mozilla's AMO (addons.mozilla.org) infrastructure. This can be bypassed in Firefox Nightly and ESR builds via xpinstall.signatures.required = false, or permanently with the Nightly/Developer Edition variants. The enforcement protects against unsigned malicious extensions but creates a dependency on Mozilla's signing infrastructure.
All behaviors documented against Firefox release channel unless stated. ESR behavior may differ in minor version prefs. Chromium-based browsers do not share these mechanisms.