A desktop displays hardened browser privacy settings, encrypted DNS, and configuration files beside a keyboard and plants.
Firefox 159 is the current stable build for this walkthrough. Mozilla's administrator notes say it shipped on October 27, 2026 and that the same notes cover Firefox ESR 153.6.0, with ESR 153 as the current extended-support line. A stock Firefox install is a decent privacy baseline, but it leaves telemetry and sponsored suggestions switched on. Turning it into a deliberately hardened browser takes a separate profile, a small user.js, an installation-level policies.json, and a check that Firefox accepted your settings.

Below is a cleaned-up, version-scoped version of that process. Some of the settings in the popular 12-step guide are corrected here, because several details need care: the policy file, the extension controls, and the verifier script.

A desktop displays hardened browser privacy settings, encrypted DNS, and configuration files beside a keyboard and plants. What this setup does and does not do​

A hardened Firefox reduces what third parties learn about you through the browser. It is not an anonymity tool.

  • It helps with: cross-site tracking, plain-text DNS lookups visible to your local network, and vendor-side telemetry and sponsored suggestions.
  • It does not help with: your IP address (every site still sees it), account-based tracking once you sign in, or malware on the machine.
  • Fingerprinting: protection reduces some signals. It does not promise you will blend in perfectly.

Every extra tweak also makes your configuration rarer, and a rare configuration is itself a signal. Fewer, understood changes beat a maximal list.

Prerequisites​

  • Firefox 159, or ESR 153.6.0 if you prefer slower feature churn.
  • Admin rights, because policies.json lives in the installation directory.
  • Python 3 and a Unix-style shell if you want to run the helper scripts. Windows users can use WSL or adapt the paths.
  • A backup of anything you care about. Clear-on-shutdown rules will sign you out of sites.

Firefox now ships on a two-week cadence. Mozilla's support blog says the new rhythm began with Firefox 155 on September 1, 2026. Mozilla's stated goal is to get fixes and completed features to users sooner and more predictably. That is a good reason to re-test your config after major updates. The same post notes dot releases can still happen when needed, so treat "every two weeks" as a rhythm and not a guarantee.

Step 1: Use a dedicated profile​

Close Firefox, then create a profile from a terminal (Linux-style example):

Code:
mkdir -p "$HOME/firefox-private"
firefox -CreateProfile "private $HOME/firefox-private"
firefox -P private --no-remote &

Open about:profiles to confirm the profile exists and to see its root folder. That folder is where user.js goes. Your daily profile stays untouched until you decide to switch.

Step 2: Strict tracking protection​

In Settings, open Privacy & Security and choose Strict under Enhanced Tracking Protection. Strict blocks more but can break some sites. You can fix a broken site from the shield icon in the address bar.

To pin this in a profile, use:

user_pref("browser.contentblocking.category", "strict");

Step 3: Choose one fingerprinting path​

  • Middle path (recommended for most people): Strict mode plus privacy.fingerprintingProtection set to true.
  • Heavy path: privacy.resistFingerprinting. It forces uniform values such as UTC time and a rounded window size, and it breaks more sites.

Pick one and use it consistently. Mixing approaches across machines makes each browser look unusual. Preference names change between releases, and a misspelled or retired pref does nothing and raises no error. Check each name in about:config on your build.

Step 4: Encrypted DNS, with eyes open​

DNS over HTTPS (DoH) keeps your local network from reading site lookups. It does not hide your IP from sites, and it does not affect cookies or fingerprinting. It moves query visibility to your chosen resolver, so read that operator's retention policy.

Mozilla's policy reference explains how the settings map to resolver behaviour:

  • With the policy Enabled: true and the default Fallback: true, network.trr.mode is 2. Firefox tries DoH first and falls back to the system resolver.
  • With Enabled: true and Fallback: false, the mode is 3. Firefox uses only DoH, and a failed lookup is an error.

Mode 3 is the stricter choice, but if the resolver is unreachable you lose name resolution. That includes internal hostnames on managed or corporate networks. The policy supports an ExcludedDomains list so those names resolve through the system resolver. Encrypted DNS can also bypass local filtering and parental controls, so think twice on shared or managed networks.

If pages stop loading after you pick mode 3, switch to mode 2 temporarily and check the provider URL.

Step 5: Trim telemetry and sponsored content​

You can turn off health-report upload, studies and sponsored suggestions in Settings, or pin them in user.js:

Code:
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("app.shield.optoutstudies.enabled", false);
user_pref("browser.newtabpage.activity-stream.showSponsored", false);
user_pref("browser.urlbar.suggest.quicksuggest.sponsored", false);

Be selective. Mozilla's own policy documentation for disabling telemetry says Mozilla recommends against it, since the data is used to improve the product. That is your call. Just don't mistake it for an endorsement. Do not disable updates or Remote Settings in the name of privacy. It leaves known flaws unpatched.

Step 6: Put durable settings in user.js​

Firefox rewrites prefs.js freely. A user.js file in the profile root is applied on each launch. A compact, understandable starter:

Code:
user_pref("browser.contentblocking.category", "strict");
user_pref("privacy.query_stripping.enabled", true);
user_pref("privacy.fingerprintingProtection", true);
user_pref("dom.security.https_only_mode", true);
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("app.shield.optoutstudies.enabled", false);
user_pref("browser.newtabpage.activity-stream.showSponsored", false);
user_pref("browser.urlbar.suggest.quicksuggest.sponsored", false);
user_pref("browser.search.suggest.enabled", false);

Don't paste in a giant template wholesale. The arkenfox project is useful reading, but its hundreds of prefs each carry a trade-off, and wholesale copying is a classic way to break video calls and banking sites. Two other settings deserve a test before you commit. media.peerconnection.ice.default_address_only can affect video calls, and geo.enabled set to false disables location lookups entirely.

Restart, open about:config, and search for one of your prefs. A value set from user.js shows as modified. If it shows the default, Firefox did not read the file. The usual cause is the wrong folder or a hidden .txt extension.

Step 7: policies.json for installation-level control​

user.js can be edited by anything with profile access. policies.json works at the installation level and can lock settings. Mozilla documents the locations:

  • Windows: a distribution folder next to the Firefox executable.
  • macOS: Firefox.app/Contents/Resources/distribution.
  • Linux: distribution inside the Firefox installation directory, which varies by distribution. Alternatively, system-wide policy can go in /etc/firefox/policies.
  • Flatpak: the sandbox cannot read the host's /etc/firefox/policies. Mozilla's guide describes a separate org.mozilla.firefox.systemconfig extension directory instead.

So /usr/lib/firefox/distribution is common on Linux but is not universal. Fedora-family systems, for example, are often reported to use /usr/lib64/firefox/distribution. Check your own install.

A privacy-oriented example. Note the added Category line:

Code:
{
  "policies": {
    "DisableTelemetry": true,
    "DisableFirefoxStudies": true,
    "EnableTrackingProtection": {
      "Value": true,
      "Locked": true,
      "Category": "strict",
      "Cryptomining": true,
      "Fingerprinting": true,
      "EmailTracking": true
    },
    "DNSOverHTTPS": {
      "Enabled": true,
      "ProviderURL": "[url]https://mozilla.cloudflare-dns.com/dns-query[/url]",
      "Locked": true,
      "Fallback": true
    },
    "HttpsOnlyMode": "force_enabled"
  }
}

Mozilla's reference describes Category as a string that sets the tracking protection category, either strict or standard. Without it, a policy that only enables tracking protection does not by itself enforce Strict. Per the compatibility table, Category has been available since Firefox 141 and ESR 140.1. I set Fallback to true here for usability. Switch it to false only if you accept the availability risk described in Step 4.

Shutdown clearing: mind the policy details​

The SanitizeOnShutdown policy accepts specific data types. Mozilla's reference says that when set as an object, any member omitted is treated as false, and that its Sessions option clears active logins. That is different from clearing cookies alone and will sign you out. Mozilla also says ClearOnShutdown supersedes this policy in Firefox 158 and later. If you use both, don't assume the older one wins.

Confirm it loaded​

Restart Firefox and open about:policies. The Active tab should list your policies. An empty list or an error usually means malformed JSON or the wrong directory. Validate first with python3 -m json.tool policies.json.

Step 8: Extensions, with realistic expectations​

A content blocker such as uBlock Origin catches things built-in lists miss. Install it from addons.mozilla.org and leave default lists alone for a week. Each extra extension is more risk, since an add-on can read page content.

ExtensionSettings can block, allow or force-install add-ons. It also has a wildcard allow-list model, where only named extensions install. Mozilla's reference notes that host permissions are ignored by blocked_permissions. So don't assume a policy broadly constrains what an extension can see on a page. Treat it as an install-control tool, and vet the publisher and add-on ID yourself. A malformed entry can also invalidate policy handling, so re-check about:policies after edits.

Step 9: Containers​

Containers separate cookie storage by group of sites: Banking, Social, Shopping, and so on. They do not stop a service from recognizing you once you log in. Firefox 158 added container assignment via the SitePolicies policy, including an ephemeral option. Mozilla's reference says ephemeral containers clear after the last tab closes and at normal shutdown. Policy-created containers are not shown in the normal containers UI or selectable from its menu. A crash can leave data behind, so "ephemeral" describes deletion timing, not "never written to disk." Start with three containers at most, so you can remember what lives where.

Step 10: Permissions and search​

  • Default location to blocked and camera and microphone to ask, then grant per site.
  • Turn off live search suggestions if you don't want each keystroke in the address bar sent to your search provider.
  • Disable form autofill if you want to remove the hidden-field capture route, and use a dedicated password manager.

Step 11: Verify what Firefox accepted​

A verifier is worth having, but it needs care. Firefox merges user.js values at startup and writes them back to prefs.js on a clean exit. So the check order matters: start Firefox, browse briefly, quit normally, then compare. Run it on your own profile and test it against both a passing and a deliberately broken config before you trust it.

Be careful about the prefs-file format. prefs.js uses the same user_pref("name", value); form as user.js, so a parser built for that format applies to both. One caveat applies: a value can be accepted but then not written back, for example a pref Firefox treats as default. Treat a MISSING line as a prompt to investigate, not proof of failure.

Also be clear about what a policy checker proves. Seeing five top-level key names in your JSON shows only that the file contains them. It does not prove Firefox loaded the file, that values are valid, or that it sits in the directory Firefox reads. The authoritative check is about:policies.

Step 12: Confirm each layer​

LayerCheckPass condition
Policiesabout:policies, Active tabYour keys are listed
Prefsabout:config or your verifierValues match your user.js
DNSabout:networking#dnsLookups show TRR as true
TrackersShield icon on a media-heavy siteBlocked trackers are listed
CookiesRestart, then visit signed-in sitesSigned out unless allow-listed

Treat public fingerprint-test sites as rough guides, since each measures a different slice. Run one before and after, and look for your values blending in, not a perfect score.

Common failures and fixes​

  • Firefox ignores user.js: it is in the wrong folder. Use Open Folder beside the profile you actually launched in about:profiles.
  • about:policies is empty: invalid JSON or wrong directory. Validate the JSON and check your install type (Flatpak, Snap, distro package).
  • Nothing loads after enabling DoH mode 3: the resolver is unreachable. Drop to mode 2 and check the URL.
  • Signed out everywhere: clear-on-shutdown is working as written. Add exceptions or disable the cookie and session clearing.
  • Video calls fail: remove the WebRTC address pref and retest.
  • A pref does nothing: it may have been renamed or retired. Look it up in about:config.
  • Settings revert after an update: a package update can replace the distribution folder. Keep your kit in version control and reapply.

If none fits, reproduce the problem in a throwaway profile with no user.js or policy file. If it works there, bisect your user.js in halves.

Claims to treat with caution​

Some figures in the original walkthrough could not be confirmed from Mozilla's primary documentation and are left out here: the "weekly" build claim (Mozilla describes a two-week cycle), the Copy Clean Link "130 additional parameters" detail, and some future-version dates. Verify release timing and new features against Mozilla's own pages before relying on them.

Bottom line​

The best version of this project is simple: a separate profile, a few settings you understand, an installation-level policy file for the ones you want locked, and a routine check after major updates. Strict tracking protection, encrypted DNS with a deliberate fallback choice, and telemetry off cover the main browser-side leaks. Everything beyond that is a trade of convenience for a smaller, rarer fingerprint.

 

References

  1. Firefox Privacy Browser Setup: 12 Steps, 60 Min (2026) - shattered.io shattered.io 2026-11-05T23:42:58+00:00
  2. Firefox 159 release notes | Firefox administrator reference firefox-admin-docs.mozilla.org
  3. Configuring policies | Firefox administrator reference firefox-admin-docs.mozilla.org