JavaScript Shell

README.md

Firefox hardening

Build Status

What's all this then?

This is a user.js configuration file for Mozilla Firefox that's supposed to harden Firefox's settings and make it more secure.

Main goals

  • Limit the possibilities to track the user through web analytics
  • Harden the browser, so it doesn't spill its guts when asked (have you seen what BeEF can do?)
  • Limit the browser from storing anything even remotely sensitive persistently (mostly just making sure private browsing is always on)
  • Make sure the browser doesn't reveal too much information to shoulder surfers
  • Harden the browser's encryption (cipher suites, protocols, trusted CAs)
  • Hopefully limit the attack surface by disabling various features
  • Still be usable in daily use

How to achieve this?

There are several parts to all this and they are:

  • Running a selected list of browser extensions
  • Using the user.js settings file itself
  • Using the cas.sh script to limit the CAs


How to use the user.js file

Download

Different download methods are available:

  • Clone using git: git clone https://github.com/pyllyukko/user.js
  • Download and extract the ZIP file containing the latest version.
  • Download the latest user.js directly

Installation

Install for a single profile

Copy user.js in your current user profile, or (recommended) to a fresh, newly created Firefox profile directory.

The file should be located at:

OS Path
Windows 7 %APPDATA%\Mozilla\Firefox\Profiles\XXXXXXXX.your_profile_name\user.js
Linux ~/.mozilla/firefox/XXXXXXXX.your_profile_name/user.js
OS X ~/Library/Application Support/Firefox/Profiles/XXXXXXXX.your_profile_name
Android /data/data/org.mozilla.firefox/files/mozilla/XXXXXXXX.your_profile_name and see issue #14
Sailfish OS + Alien Dalvik /opt/alien/data/data/org.mozilla.firefox/files/mozilla/XXXXXXXX.your_profile_name
Windows (portable) [firefox directory]\Data\profile\

Do note that these settings alter your browser behaviour quite a bit, so it is recommended to either create a completely new profile for Firefox or backup your existing profile directory before putting the user.js file in place.

Install system-wide

Create local-settings.js in Firefox installation directory, with the following contents:

pref("general.config.obscure_value", 0);
pref("general.config.filename", "mozilla.cfg");

This file should be located at:

OS Path
Windows C:\Program Files (x86)\Mozilla Firefox\default\pref\
Linux This file is not required
OS X /Applications/Firefox.app/Contents/Resources/defaults/pref

In user.js, Change user_pref( to one of:

  • pref( (the value will be used as default value on Firefox profile creation, it can be changed in about:config)
  • lockPref( (the value will be used as default value on Firefox profile creation, will be locked and can't be changed) in user.js or in Firefox's about:config or settings.

Copy user.js to the Firefox installation directory. The file should be located at:

OS Path
Windows C:\Program Files (x86)\Mozilla Firefox\mozilla.cfg
Linux /etc/firefox/firefox.js
Linux (Debian) /etc/firefox-esr/firefox-esr.js
OS X /Applications/Firefox.app/Contents/Resources/mozilla.cfg

Updating using git

For any of the above methods, you can keep your browser's user.js with the latest version available here: Clone the repository, and create a symoblic link from the appropriate location to the user.js file in the repository. Just run git pull in the repository when you want to update, then restart Firefox:

cd ~/.mozilla/firefox
git clone 'https://github.com/pyllyukko/user.js.git'
cd XXXXXXXX.your_profile_name
ln -s ../user.js/user.js user.js

Verifying

Verify that the settings are effective from about:support (check the "Important Modified Preferences" and "user.js Preferences" sections).


What does it do?

There's a whole lot of settings that this modifies and they are divided in the following sections or categories:

  • HTML5 / APIs / DOM
  • Miscellaneous
  • Extensions / plugins related
  • Firefox (anti-)features / components
  • Automatic connections
  • HTTP protocol related
  • Caching
  • UI related
  • TLS / HTTPS / OCSP related
  • Cipher suites

Some of the settings in this user.js file might seem redundant, as some of them are already set to the same values by default. However, the user.js file has this nice property, that even if you go change any of these settings through about:config, they're reset to the user.js defined values after you restart Firefox. So user.js makes sure they're back at the secure default values always when you start your browser. That way, it also makes experimenting with different settings easier.

Here are some of the "highlights" from each category. For a full list of settings and references, check the user.js file itself.

HTML5 / APIs / DOM

Miscellaneous

Extensions / plugins related

It is common for client side attacks to target browser extensions, instead of the browser itself (just look at all those Java and Flash vulnerabilities). Make sure your extensions and plugins are always up-to-date.

Firefox features

Automatic connections

This section disables some of Firefox's automatic connections.

Do note, that some automatic connections are still intentionally left out (as in not disabled), namely the following:

See also #20.

HTTP

Caching

UI related

TLS / HTTPS / OCSP related

Ciphers

This section tweaks the cipher suites used by Firefox. The idea is to support only the strongest ones with emphasis on forward secrecy, but without compromising compatibility with all those sites on the internet. As new crypto related flaws are discovered quite often, the cipher suites can be tweaked to mitigate these newly discovered threats.

Here's a list of the ciphers with default config and Firefox 38.8.0 ESR:

Cipher Suites (11 suites)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
    Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
    Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
    Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
    Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)

Here's the list with this config:

Cipher Suites (6 suites)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
    Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
    Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
    Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)

This is not enough!

Here's some other tips how you can further harden Firefox:

  • Keep your browser updated! If you check Firefox's security advisories, you'll see that pretty much every new version of Firefox contains some security updates. If you don't keep your browser updated, you've already lost the game.
  • Disable all unnecessary extensions and plugins!
  • Create different profiles for different purposes
  • Change the Firefox's built-in tracking protection to use the strict list
  • Change the timezone for Firefox by using the TZ environment variable (see here) to reduce it's value in browser fingerprinting
  • Completely block unencrypted communications using the HTTPS Everywhere toolbar button > Block all unencrypted requests. This will break websites where HTTPS is not available.

Add-ons

Here is a list of the most essential security and privacy enhancing add-ons that you should consider using:

Tracking protection

Tracking protection is one of the most important technologies that you need. The usual recommendation has been to run the Ghostery extension, but as it is made by a potentially evim(tm) advertising company, some people feel that is not to be trusted. One notable alternative is to use uBlock, which can also be found at Mozilla AMO.

Ghostery is still viable option, but be sure to disable the GhostRank feature.

Do note, that this user.js also enables Mozilla's built-in tracking protection, but as that's quite new feature it is to be considered only as a fallback and not a complete solution. As it utilizes Disconnect's list, recommending Disconnect seems redundant.

So to summarize, pick one between Ghostery and uBlock, depending on your personal preferences.

See also:

Add-ons for mobile platforms

Online tests

HTML5test

HTML5test

Here's a comparison of the various supported HTML5 features between recent Firefox with these settings, stock Firefox and the Tor Browser:

Comparison user.js version Firefox version Firefox baseline Tor Browser
html5test 3041fb7204f2547a34083fba7db2009929ed2326 36.0.1 35 4.0.4

Known problems

There are plenty! Hardening your browser will break your interwebs. Here's some examples:

  • If you get "TypeError: localStorage is null", you probably need to enable local storage (dom.storage.enabled == true)
  • If you get "sec_error_ocsp_invalid_signing_cert", it probably means that you don't have the required CA
  • If you get "ssl_error_unsafe_negotiation", it means the server is vulnerable to CVE-2009-3555 and you need to disable security.ssl.require_safe_negotiation (not enabled currently)
  • If you set browser.frames.enabled to false, probably a whole bunch of websites will break
  • Some sites require the referer header (usually setting network.http.sendRefererHeader == 2 is enough to overcome this and the referer is still "spoofed")
  • The IndexedDB is something that could potentially be used to track users, but it is also required by some browser add-ons in recent versions of Firefox. It would be best to disable this feature just to be on the safe side, but it is currently enabled, so that add-ons would work. See the following links for further info:
  • Firefox Hello requires WebRTC, so you'll need to enable media.peerconnection.enabled & media.getusermedia.screensharing.enabled and apparently disable security.OCSP.require.
  • Captive portals might not let OCSP requests through before authentication, so setting security.OCSP.require == false might be required before internet access is granted
  • DNT is not set, so you need to enable it manually if you want (see the discussion in issue #11)
  • The network.http.referer.spoofSource and network.http.sendRefererHeader settings seems to break the visualization of the 3rd party sites on the Lightbeam extension
  • You can not view or inspect cookies when in private browsing (see https://bugzil.la/823941)
  • Installation of user.js causes saved passwords to be removed from the Firefox (see #27)
  • Some payment gateways require third-party cookies to be fully enabled before you can make purchases on sites that use them (network.cookie.cookieBehavior == 0). Enabling network.cookie.thirdparty.sessionOnly will limit their lifetime to the length of the session no matter what.
  • On some Android devices, all the pages might be blank (as seen here) if the setting layers.acceleration.disabled is set to true. For more information, see #136.

The web console is your friend, when websites start to break.

CAs

It all started when I read this blog post...

So another part of my browser hardening was to somehow reduce the number of CAs trusted by my browser. First I thought I would sniff all the HTTPS connections and extract the certificates from there, to get the list of CAs I really need.

Then I came up with an better idea. I'd use certpatrol to record the certs from the HTTPS sites I visit. There was just one problem, certpatrol only stores the fingerprint of the issuer cert, which is usually a intermediate CA. So I needed to get the root CA of the intermediate CA. The solution for this to use Firefox's cert8.db to extract the intermediate CAs and get the issuer (root CA) from there.

So I wrapped up a script that uses the certpatrol's SQLite DB and Mozilla's certutil to establish a list of required root CAs from the HTTPS sites that you have visited.

There's also a ready made list built in into the script, that has 28 root CAs in it. With this list of CAs you should already be able to browse the web quite freely. Of course there might also be some geographical variations as to what CAs "are required" for normal use.

This script requires that you have the CA certificates in /usr/share/ca-certificates/mozilla (see https://packages.debian.org/search?keywords=ca-certificates). Red Hat based systems have a different model for this, so the script doesn't currently work on those (see #140).

Examples

Do note, that in order for all this to work, you MUST remove or rename Firefox's default CA list that is stored inside libnssckbi.so as described here.

Check the current list of CAs in cert8.db

cas.sh -P ~/.mozilla/firefox/XXXXXXXX.current_profile -r

Import CAs

First check which CAs would be imported (dry-run):

cas.sh -p ~/.mozilla/firefox/XXXXXXXX.reference_profile -A

Then import the required CAs to new profile:

cas.sh -p  ~/.mozilla/firefox/XXXXXXXX.reference_profile -P ~/.mozilla/firefox/XXXXXXXX.new_profile -a

Verify that it worked

After you have run the script, verify from Firefox's certificate settings, that the list is indeed limited:

Firefox certificates

The default list

This is the default CA list, that you can use. It should be enough for basic use for the most biggest/popular sites. Of course this still depends on where you are located and what sites/services/etc. you use. If you know some popular site, that is not accessible with this root CA list, please let me know and I'll consider adding it to the list.

Root CA Used by
AddTrust External CA Root https://www.debian.org/
Baltimore CyberTrust Root
COMODO Certification Authority
Deutsche Telekom Root CA 2
DigiCert High Assurance EV Root CA https://www.facebook.com/
DigiCert Global Root CA https://duckduckgo.com/
Entrust.net Secure Server Certification Authority
Entrust.net Certification Authority (2048)
Entrust Root Certification Authority https://www.ssllabs.com/
Equifax Secure Certificate Authority
GTE CyberTrust Global Root
GeoTrust Global CA https://www.google.com/
GeoTrust Primary Certification Authority https://www.robtex.com/
GeoTrust Primary Certification Authority - G3
GlobalSign Root CA https://www.wikipedia.org/
Go Daddy Class 2 Certification Authority
Go Daddy Root Certificate Authority - G2
Starfield Class 2 Certification Authority https://tools.ietf.org/
StartCom Certification Authority
UTN-USERFirst-Hardware
ValiCert Class 2 Policy Validation Authority
VeriSign Class 3 Public Primary Certification Authority - G3 https://www.mysql.com/
VeriSign Class 3 Public Primary Certification Authority - G5 https://twitter.com/
thawte Primary Root CA
thawte Primary Root CA - G3
SecureTrust CA
QuoVadis Root CA 2 https://supportforums.cisco.com/
DST Root CA X3 Let's Encrypt

How to use the default list

Import the default CA list with:

cas.sh -C -P ~/.mozilla/firefox/XXXXXXXX.new_profile -a

TODO

Contributing

Yes please! All issues and pull requests are more than welcome. Please try to break down your pull requests or commits into small / manageable entities, so they are easier to process. All the settings in the user.js file should have some official references to them, so the effect of those settings can be easily verified from Mozilla's documentation.

For more information, see https://github.com/pyllyukko/user.js/blob/master/CONTRIBUTING.md.

References