How can I disable signature checking for Firefox add-ons?

It is only possible to disable addons verification in Nightly and Developer channel. In other words it is not possible in Beta versions and standard releases.

  1. Go to about:config (enter it into address bar)
  2. Set xpinstall.signatures.required to false.

More at https://wiki.mozilla.org/Addons/Extension_Signing


Disable add-on signing check in Release (all) versions of Firefox

Firefox version 65+ (or so)

The following instructions will disable signature checking on Firefox for the Firefox profile in which you install the files. You are going to be adding some files to the chrome directory under your Firefox Profile directory.

This code will not work if javascript.enabled is set to False in about:config. That option needs to be set to True, which is the default setting.

As of Firefox 69+, it is expected that, in addition to the instructions below, you will need to have toolkit.legacyUserProfileCustomizations.stylesheets set to true in about:config. If it does not exist, then you will need to create it ("new" in the right-click context menu) as a Boolean option. See Bugzilla 1541233 for more detail about the addition of this option.

I've tested this on Firefox 66.0.3+.

The process of upgrading versions appears to briefly run the browser code with these changes not active. Thus, the first time you run a new version of Firefox any extensions you have installed that rely on disabling add-on signing will be disabled. You can immediately re-install those extensions after the upgrade to a new Firefox version and the extensions should resume working.

IIRC, some slightly different code was needed for Firefox 65, I believe I left that code in disable-add-on-signing.js when I modified it for Firefox 66, but I'm not sure about that.

We're going to use a technique which allows you to run arbitrary JavaScript code in the browser context from files stored in your Firefox profile directory. I found how to do this from Haggai Nuchi's GitHub repository: Firefox Quantum compatible userChrome.js.

On Windows, your Firefox profile directory will be %appdata%\Mozilla\Firefox\Profiles\[profileID]. If you have only one profile, the [profileID] will be the only directory in the %appdata%\Mozilla\Firefox\Profiles directory. If you have multiple profiles, you will need to select the one(s) you want to install this hack into.

Once you get to your profile directory, your will need to create a directory called chrome, if it does not already exist. You will be adding the 3 files below to that directory:

  • userChrome.css
  • userChrome.xml
  • disable-add-on-signing.js

You will then need the following code in userChrome.css, which is available from Haggai Nuchi's GitHub repository:

/*Enable userChrome.js */
/* Copyright (c) 2017 Haggai Nuchi
Available for use under the MIT License:
https://opensource.org/licenses/MIT
*/

@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);

toolbarbutton#alltabs-button {
    -moz-binding: url("userChrome.xml#js");
}

You will need userChrome.xml (slightly modified from the version available in Haggai Nuchi's GitHub repository):

<?xml version="1.0"?>
<!-- Copyright (c) 2017 Haggai Nuchi
Available for use under the MIT License:
https://opensource.org/licenses/MIT
 -->
<!-- This has been slightly modified from the version available from
https://github.com/nuchi/firefox-quantum-userchromejs/blob/master/userChrome.xml
by Makyen. The modified version is released under both the MIT and CC BY-SA 3.0 licenses.
 -->

<bindings id="generalBindings"
   xmlns="http://www.mozilla.org/xbl"
   xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   xmlns:xbl="http://www.mozilla.org/xbl">

  <binding id="js" extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-badged">
    <implementation>
        <constructor><![CDATA[
            function makeRelativePathURI(name) {
              let absolutePath = Components.stack.filename;
              return absolutePath.substring(0, absolutePath.lastIndexOf("/") + 1) + name;
            }
            // The following code executes in the browser context,
            // i.e. chrome://browser/content/browser.xul
            try {
                Services.scriptloader.loadSubScript(makeRelativePathURI("disable-add-on-signing.js"), window);
            } catch(e) {
                console.error(e);
            }
        ]]></constructor>
    </implementation>
  </binding>
</bindings>

You will also need disable-add-on-signing.js:

//This should be installed as the file disable-add-on-signing.js in
//  your profile's "chrome" directory.

//Earlier versions of Firefox
try {
    Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {}).eval("SIGNED_TYPES.clear()");
} catch(ex) {}
try {
    Components.utils.import("resource://gre/modules/addons/XPIInstall.jsm", {}).eval("SIGNED_TYPES.clear()");
} catch(ex) {}
try {
    Components.utils.import("resource://gre/modules/addons/XPIDatabase.jsm", {}).eval("SIGNED_TYPES.clear()");
} catch(ex) {}

//Tested on Firefox 66
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
    XPIDatabase: "resource://gre/modules/addons/XPIDatabase.jsm",
});
XPIDatabase.SIGNED_TYPES.clear();

console.log('Add-on signing disabled.');

After adding these files in your profile's chrome directory, you will need to restart Firefox. You can verify that the code is running by looking for "Add-on signing disabled." in the Browser Console.

Add-ons which were disabled or removed by Firefox will not be automatically enabled. You will need to re-install them. You can install them by draging-and-droping the *.xpi file onto a Firefox window and confirming that you want to install.

If you are wanting to get the *.xpi file for any particular extension from Mozilla Add-ons you can download it by right clicking on the "install" button and selecting "Save As", or "Remove".

Firefox version 57 or earlier (or so)

Unfortunately, I don't recall with which version of Firefox this this method stopped working. I know I was using it on Firefox 54, 55, 52ESR and FF56.*.

I initially found this solution for disabling forced add-on signature checking in this blog post, which is the original source for the (somewhat modified) code in this answer. Making these changes will allow you to install unsigned add-ons into profiles using the Firefox distribution you modify. For most people, this will be your main Firefox installation. However, if you have installed multiple versions, you will need to make this modification in each installation. However, once you make the modifications, they will remain through normal Firefox updates.

You will need to add a couple of files within the Firefox installation directory. You can find a list of installation directory examples for Windows, Linux, and Mac OS on mozillaZine. The most common install directories are:

  • Windows
    • C:\Program Files\Mozilla Firefox\
    • C:\Program Files (x86)\Mozilla Firefox\
  • Linux
    • /usr/lib/firefox-<version>
  • OSX
    • /Applications/Firefox.app

Add first file

You then need to add code below as the file <Install directory>/defaults/pref/disable-add-on-signing-prefs.js (Windows: <Install directory>\defaults\pref\disable-add-on-signing-prefs.js):

//This file should be placed in the defaults/pref directory (folder)
//within the Firefox installation directory with the with the name:
//  disable-add-on-signing-prefs.js
pref("general.config.obscure_value", 0);
pref("general.config.filename", "disable-add-on-signing.js");

Add second file

You also need to add the code below as the file <Install directory>/disable-add-on-signing.js (Windows: <Install directory>\disable-add-on-signing.js):1

//This file should be placed in the Firefox installation directory
//(folder) with the with the name:
//  disable-add-on-signing.js
try {
    Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {})
              .eval("SIGNED_TYPES.clear()");
} catch(ex) {}
try {
    Components.utils.import("resource://gre/modules/addons/XPIInstall.jsm", {})
              .eval("SIGNED_TYPES.clear()");
} catch(ex) {}

Results

I've been using these solutions for years now to have a few extensions I built for my own use installed and to test new versions of extensions I'm working on (when I want to test in the Release version instead of Firefox Developer Edition or Nightly).

NOTE: In about:addons Firefox may show (under some conditions) the add-on as enabled (not greyed-out), but have text stating that the add-on "could not be verified and has been disabled". The text is not accurate! The add-on is enabled and functioning.

How it works

Within resource://gre/modules/addons/XPIProvider.jsm the const SIGNED_TYPES is defined as a Set. In order for an add-on to require signing, its type must be a member of that Set. The Set.prototype.clear() method is used to clear all entries from the Set. This results in no add-on types which require signing (code 1, code 2).

If you wanted to, you could individually disable the signature check for any of the types: "webextension", "extension", "experiment", or "apiextension".

Remove the META-INF directory from any modified extension

The additional files in the sections above turn off the requirement that extensions must be signed. If the signature files exist, the signature will still be verified. Thus, if you have modified an extension from one that was singed and have not removed the signature files, the extension will fail signature verification. In other words, actually checking any existing signatures is a separate step from the requirement that the signature must exist.

If you have modified an extension which had been signed (you can tell that it had been signed by the existence of a META-INF directory in the extension's root directory), then you will need to remove the signature files. You can do this by removing the META-INF directory and all files contained in that directory.


1. The code in the blog puts this call in a try{}catch(){} block. There's really no need to do so. The only effective thing that doing so does is prevent any error from being reported in the Browser Console (Ctrl-Shift-J, or Cmd-Shift-J on OSX). There's no additional code that is desired to be run if this fails. In addition, I would prefer to be able to see the error in the Browser Console if this fails in order to know that it has, in fact, failed. Not having the try{}catch(){} doesn't have any negative effects and permits tracking down the problem if, on some future version of Firefox, add-ons start being disabled because of not being signed.