Python 3, a text editor, and Firefox installed. Steps 1–4 use a scratch folder and never touch your browser or its settings — you can do the whole lab with Firefox closed.
You need no prior about:config experience. The one thing to know is that Firefox keeps its settings in plain text files inside a profile folder, and that is what the lab reads.
🔴 Close Firefox before step 5. It writes prefs.js when it exits, not while it runs, so checking a live profile reports stale values and will mislead you.
Why Harden Firefox?
Firefox is one of the most privacy-respecting mainstream browsers available, but its default settings still leave room for improvement. Out of the box, Firefox sends telemetry data to Mozilla, allows websites to fingerprint your browser, and does not block all trackers. With a few targeted changes, you can significantly reduce your digital footprint while keeping the browser fully functional for everyday use.
These changes are designed for general-purpose privacy. If you need maximum anonymity (whistleblowing, activism in hostile countries), consider using Tor Browser instead. The goal here is to make everyday browsing significantly more private without breaking most websites.
This guide covers Firefox on all desktop platforms (Windows, macOS, Linux). The settings menus and about:config entries are identical across operating systems. Make sure you are running the latest version of Firefox before proceeding.
Enhanced Tracking Protection
Firefox includes a built-in tracking protection system called Enhanced Tracking Protection (ETP). By default, it runs in Standard mode, which blocks known third-party trackers and cryptominers. Switching to Strict mode significantly expands what gets blocked.
Enabling Strict Mode
about:preferences in the address bar and press Enter.
Strict mode blocks the following:
- Social media trackers (Facebook, Twitter tracking pixels)
- Cross-site cookies in all windows (not just private browsing)
- Tracking content in all windows (Standard only blocks in private windows)
- Cryptominers that hijack your CPU
- Known fingerprinting scripts
Strict mode may occasionally break website functionality, particularly sites that rely on third-party authentication or embedded content. If a site breaks, click the shield icon in the address bar and toggle off Enhanced Tracking Protection for that specific site.
Essential about:config Tweaks
Firefox has hundreds of hidden configuration options accessible through about:config.
These settings give you fine-grained control over privacy-related behavior that is not exposed
in the normal settings interface.
about:config in the address bar and press Enter. Click
Accept the Risk and Continue when warned.
Use the search bar at the top to find each setting. Double-click a boolean value to toggle it, or click the pencil icon to edit string/integer values.
Disable Telemetry
Mozilla collects usage data by default. While they state it is anonymized, there is no reason to send any data if you value privacy. Change these settings:
toolkit.telemetry.enabled = false
toolkit.telemetry.unified = false
toolkit.telemetry.archive.enabled = false
datareporting.healthreport.uploadEnabled = false
datareporting.policy.dataSubmissionEnabled = false
browser.ping-centre.telemetry = false
browser.newtabpage.activity-stream.feeds.telemetry = false
browser.newtabpage.activity-stream.telemetry = false
Prevent WebRTC IP Leaks
WebRTC (Web Real-Time Communication) is used for video calls and peer-to-peer connections, but it can leak your real IP address even when using a VPN. This is one of the most important privacy tweaks you can make.
media.peerconnection.enabled = false
Disabling WebRTC will break browser-based video and voice calls (Google Meet, Jitsi,
Discord in-browser). If you need these services, set the value back to
true or use a dedicated application instead of the browser.
If you need WebRTC but still want to prevent IP leaks, use this less aggressive option instead:
media.peerconnection.ice.default_address_only = true
media.peerconnection.ice.no_host = true
Disable Pocket
Pocket is a read-it-later service owned by Mozilla. It is integrated into Firefox and shows recommended articles on the new tab page. Disabling it removes this integration entirely.
extensions.pocket.enabled = false
Disable Firefox Suggestions and Sponsored Content
browser.urlbar.suggest.quicksuggest.sponsored = false
browser.urlbar.suggest.quicksuggest.nonsponsored = false
browser.newtabpage.activity-stream.showSponsored = false
browser.newtabpage.activity-stream.showSponsoredTopSites = false
Disable Prefetching
Firefox can prefetch pages and DNS entries it thinks you might visit next. While this speeds up browsing, it also sends requests to servers you never intended to visit.
network.prefetch-next = false
network.dns.disablePrefetch = true
network.predictor.enabled = false
network.http.speculative-parallel-limit = 0
Cookie and History Settings
Cookies are small files that websites store in your browser. They serve legitimate purposes (keeping you logged in) but are also heavily abused for tracking you across the web. Firefox gives you several layers of control over cookie behavior.
Configure Cookie Behavior
In Settings > Privacy & Security, scroll down to Cookies and Site Data. The recommended approach is:
- Keep cookies enabled (blocking all cookies breaks most websites)
- Enable Delete cookies and site data when Firefox is closed
- Use the Manage Exceptions button to whitelist sites you want to stay logged into
With this configuration, you start each browsing session with a clean slate while maintaining logins for sites you trust and use regularly (email, banking, etc.).
History Settings
Under the History section, change the dropdown to Use custom settings for history. This reveals additional options:
- Uncheck Remember browsing and download history if you want no local traces
- Uncheck Remember search and form history to prevent autofill of previous searches
- Enable Clear history when Firefox closes and click Settings to choose what gets cleared
You do not need to clear everything on every close. A practical middle ground is to clear cookies and cache on close, but keep browsing history for your own convenience. Your history is stored locally and does not leave your computer.
HTTPS-Only Mode and DNS over HTTPS
Two of the most impactful privacy features in Firefox are HTTPS-Only mode and DNS over HTTPS (DoH). Together, they encrypt both your web traffic and the DNS queries that reveal which sites you visit.
Enabling HTTPS-Only Mode
HTTPS-Only mode forces all connections to use encrypted HTTPS instead of unencrypted HTTP. If a site does not support HTTPS, Firefox will show a warning before loading it.
This ensures all your web traffic is encrypted in transit. The vast majority of modern websites support HTTPS, so you will rarely encounter the fallback warning.
Enabling DNS over HTTPS
When you type a website address, your browser sends a DNS query to translate the domain
name (like example.com) into an IP address. By default, these queries are
sent in plain text, meaning your ISP (and anyone monitoring your network) can see every
site you visit. DNS over HTTPS encrypts these queries.
Now Do It Yourself: Prove Your Privacy Settings Actually Applied
Every Firefox hardening guide, including the one above, ends the same way: change these settings. None of them tells you how to check that the changes took. That gap matters, because a mistyped preference name is stored happily and does nothing, and Firefox never says a word about it.
In about fifteen minutes you will build a small checker that compares what you asked for against what your browser actually has — and see two settings from a realistic profile silently fail. You need Python 3 and a text editor. Steps 1–4 run entirely in a scratch folder and never touch your browser; every output below came from running them. Step 5 points the finished tool at your real profile.
A note for anyone re-checking this page with an automated runner: step 4's transcript
will not reproduce, and that is expected rather than a defect. It shows the output after
you edit user.js to introduce the deliberate typo, and a runner that only re-executes
the commands never makes that edit — so it reproduces step 3's result instead. The
transcript was captured by hand, with the edit in place.
Go: open a terminal and make a scratch folder: mkdir ffcheck then cd ffcheck. Nothing here touches your real browser yet.
Do: save this as user.js. This is the exact format Firefox reads — a hardening guide that gives you a list of about:config toggles is describing this file.
// Privacy hardening — put this in your Firefox profile folder.
user_pref("privacy.resistFingerprinting", true);
user_pref("privacy.trackingprotection.enabled", true);
user_pref("network.dns.disablePrefetch", true);
user_pref("toolkit.telemetry.enabled", false);
user_pref("privacy.donottrackheader.enabled", true);
You should see: a five-line file. Check it:
user.js
Clicking through about:config and writing a user.js do the same thing. The file has one advantage that matters: you can diff it, copy it to another machine, and put it in version control. Settings you clicked exist only in that browser profile.
If not: if ls shows nothing, the file saved elsewhere. In Notepad on Windows, set Save as type to All Files or it becomes user.js.txt — which Firefox ignores completely and silently.
Go: the same folder.
Do: save this as check-prefs.py. It reads what you asked for and what Firefox actually stored, and compares them:
import re, sys, pathlib
def load(path):
"""Read user_pref lines from a Firefox prefs file. Returns {name: value-as-text}."""
out = {}
p = pathlib.Path(path)
if not p.exists():
return None
for line in p.read_text(encoding="utf-8", errors="replace").splitlines():
m = re.match(r'\s*user_pref\("([^"]+)",\s*(.+?)\);', line)
if m:
out[m.group(1)] = m.group(2).strip()
return out
wanted = load("user.js")
actual = load("prefs.js")
if wanted is None:
sys.exit("no user.js here — are you in the right folder?")
if actual is None:
sys.exit("no prefs.js here — Firefox writes it on exit; close Firefox first.")
print(f"{len(wanted)} setting(s) requested in user.js\n")
applied = missing = differs = 0
for name, want in sorted(wanted.items()):
got = actual.get(name)
if got is None:
print(f" NOT APPLIED {name}\n wanted {want}, but Firefox has no such pref")
missing += 1
elif got != want:
print(f" DIFFERENT {name}\n wanted {want}, Firefox has {got}")
differs += 1
else:
print(f" ok {name} = {got}")
applied += 1
print(f"\n{applied} applied, {differs} different, {missing} not applied")
You should see: nothing yet — it needs a prefs.js to compare against. Running it now says so:
no prefs.js here — Firefox writes it on exit; close Firefox first.
That message is the first real lesson. Firefox writes prefs.js when it closes, not while it runs, so checking a live profile shows you stale values.
If not: a SyntaxError usually means the triple-quoted docstring lost a line in copying. Copy the whole block in one go rather than line by line.
Go: the same folder.
Do: save this as prefs.js — a trimmed but realistic example of what Firefox writes:
// Mozilla User Preferences
// DO NOT EDIT THIS FILE.
user_pref("privacy.resistFingerprinting", true);
user_pref("privacy.trackingprotection.enabled", true);
user_pref("network.dns.disablePrefetch", true);
user_pref("toolkit.telemetry.enabled", true);
user_pref("browser.startup.homepage", "about:home");
Now compare them:
python3 check-prefs.py
You should see: three of your five settings took effect and two did not:
5 setting(s) requested in user.js
ok network.dns.disablePrefetch = true
NOT APPLIED privacy.donottrackheader.enabled
wanted true, but Firefox has no such pref
ok privacy.resistFingerprinting = true
ok privacy.trackingprotection.enabled = true
DIFFERENT toolkit.telemetry.enabled
wanted false, Firefox has true
3 applied, 1 different, 1 not applied
🔴 This is the situation almost nobody checks for. You followed a guide, the browser reported no error, and 40% of what you asked for is not in effect. toolkit.telemetry.enabled is still true — telemetry you believe you turned off is still on.
If not: if it reports 5 applied, your prefs.js matches user.js exactly — you probably pasted user.js into both files. The example prefs.js above deliberately differs on two lines.
Go: user.js.
Do: change one letter in a preference name — capitalise the P so it reads privacy.resistFingerPrinting. Save, and run the checker again:
python3 check-prefs.py
You should see: a third failure appears:
NOT APPLIED privacy.resistFingerPrinting
wanted true, but Firefox has no such pref
2 applied, 1 different, 2 not applied
🔴 Firefox would never have told you. Preference names are case-sensitive and unvalidated: an unknown name is simply stored as a new, meaningless preference. No warning, no red text, no entry in any log. The setting you believe protects you does nothing at all, and the only way to find out is to check — which is what you just built. Change the letter back before moving on.
If not: if the count did not change, you edited prefs.js instead of user.js, or forgot to save.
Go: your actual Firefox profile folder. Find it by opening Firefox and going to about:support, then clicking Open Folder next to Profile Folder. On Linux it is usually under ~/.mozilla/firefox/, on Windows under %APPDATA%\\Mozilla\\Firefox\\Profiles\\, on macOS under ~/Library/Application Support/Firefox/Profiles/.
Do: 🔴 Close Firefox completely first — it writes prefs.js on exit, so a running browser gives you stale answers. Then copy your user.js and check-prefs.py into that folder, start Firefox once so it reads the new settings, close it again, and run:
python3 check-prefs.py
You should see: the same report, about your real browser. Every line marked ok is a setting genuinely in force; anything else is a setting you believed you had.
This step was not re-run for this page — it depends on your own profile, and the transcripts above come from the scratch folder instead. Everything it uses was exercised in steps 1–4.
Keep both files. The next time you rebuild a machine or follow a new hardening guide, this answers “did it actually work?” in one command — a question most privacy advice never asks.
If not: no prefs.js here means you are in the wrong folder — the profile folder contains places.sqlite and cookies.sqlite, so check those are present. If settings still show as NOT APPLIED after a restart, the name is wrong or the preference was removed in your Firefox version; search it at about:config to confirm it exists.
You add user_pref("privacy.resistFingerprinting", true); to user.js, restart Firefox, and the checker still reports it as NOT APPLIED. Name two things that could be true. Answer: Either the name is wrong — case-sensitive, so resistFingerPrinting is a different, meaningless preference — or Firefox had not written prefs.js yet, because it only writes on exit and you checked while it was still running. A third possibility is that user.js is in the wrong folder, or saved as user.js.txt.
Now do it without the page: take any hardening guide you find online, turn its list of settings into a user.js, and check what fraction actually applied on your machine. If you can do that unaided, you can evaluate privacy advice instead of only following it.
Search Engine and Final Touches
Change Your Default Search Engine
Google is Firefox's default search engine, and every search you make is logged by Google and tied to your profile. Switching to a privacy-respecting search engine is one of the simplest and most effective privacy improvements you can make.
Additional Recommended Settings
A few more settings worth changing in the normal Settings interface:
- Settings > Privacy & Security > Permissions: Set Location, Camera, Microphone, and Notifications to "Block new requests" unless you actively use them
- Settings > Privacy & Security > Firefox Data Collection: Uncheck all boxes under this section
- Settings > Home: Set homepage and new tabs to "Blank Page" to avoid Mozilla's content recommendations
- Settings > General > Browsing: Uncheck "Recommend extensions as you browse" and "Recommend features as you browse"
With these changes applied, Firefox is now significantly hardened against tracking, fingerprinting, and data collection. For the next layer of protection, install privacy-focused browser extensions -- covered in the Essential Privacy Extensions tutorial.