ghacks user.js: configuring and hardening Firefox privacy, security and anti-fingerprinting
The ghacks user.js is a template which aims to provide as much privacy and enhanced security as possible and to reduce tracking and fingerprinting as much as possible – while minimizing any loss of functionality and breakage (but it will happen).
A user.js which resides in the root directory of a profile, is used to set preferences for that profile when Firefox starts. Preferences are settings that control Firefox’s behavior. Some can be set from the Options interface and all can be found in about:config, except for what are called hidden preferences which will only show when they are set by the user.
Here is how it basically works:
- Firefox starts
- Firefox reads the contents of user.js and writes to prefs.js
- It writes the active preferences, i.e not commented out
- It ignores the inactive or commented out preferences, i.e, it does not remove them from
- If the preference is already in prefs.js it will overwrite it
- It parses the user.js in the order it is written, i.e if the same preference is listed twice with two different values, the last one will be applied last
- It will abort parsing the file if it encounters a syntax error, but will still apply any content up to that error
- In FF60+, not all syntax errors cause parsing to abort, see this article
- It will not abort if you apply a data mismatch e.g if you set an integer instead of a string, it will actually write that data mismatch into prefs.js
- The user.js is now ignored until the next time Firefox starts
- Firefox opens
- The contents of prefs.js override the default values shown in about:config
- If a preference in prefs.js has a data mismatch, then it is ignored and the
defaultprevious value is retained (this could be the default or a user-set value set earlier within about:config) and shown in about:config
- In about:config
- All values stored prefs.jsin , even if they are the default value, will be denoted as status user set. In Firefox 55+ it is denoted as modifed
- If you set a value to a user set/modifed value, it is stored in prefs.js
- If you reset a value to default, it is removed from prefs.js
- If you reset a hidden preference to default, the value will be blank, and assuming it is not applied again from a user.js, it will then vanish on the next about:config reload
tl;dr: firefox starts user.js active preferences prefs.js about:config .. with caveats
That’s a bit to digest, so here is a pretty picture showing a preference with the same value as status user set/modifed and default. In about:config’s search box, you can use wildcards (e.g network*policy) to save time typing, and it is case insensitive.
And why would you want a user.js?
- It is used to reset settings on a restart, making certain preferences more or less “permanent”. You can still change preferences via about:config for testing
- It can be used to migrate a lot of settings to a new profile, and can be easily modified and deployed for multiple profiles
- There are a lot of preferences in about:config. There are over 3000 firefox ones alone. A user.js is a great repository for information. For example, it can be used as a basis for mozilla.cfg files and lockprefs.
- It can help you to better understand how to protect your privacy, enhance your security, and reduce fingerprinting
Working with a user.js
Preferences must follow Mozilla’s syntax which is user_pref(“prefname”, value);. Note that the preference name must be wrapped in quotation marks, and do not forget the semi-colon at the end. The value must also be wrapped in quotation marks, but only if it is a string. Preferences are case sensitive.