15

The latest update to Firefox (41.0b1) aggressively blocks the installation of unverified extensions, namely HTTPS Everywhere and Privacy Badger.

How might I be able to force these extensions to install? Is there a setting inside about:config I could temporarily toggle?

Mozilla highlights this change to Firefox here, noting its previous efforts to be inefficient at corralling malicious extensions.

19

Yes, there is a setting in About:config, its name is xpinstall.signatures.required. Double-click on the preference name so that its value is set to false. Now you can install unsigned extensions in Firefox. A browser restart is not needed.

  • 2
    Fantastic! This fix will suffice until EFF and others have there extensions verified. – VitaminYes Aug 12 '15 at 21:02
  • 1
    This also won't work after version 43+. :( – Suresh Atta Aug 6 '16 at 19:47
  • Despite many sources saying it won't work in recent FF, it worked for me in 48.0 on Linux. I had to open the addons page and drag the xpi file there. – That Brazilian Guy Aug 9 '16 at 13:51
  • @ThatBrazilianGato: is is not working for me on Win7 FF48.0 :( – glavić Aug 16 '16 at 13:37
  • 4
    That's it for me. Bye Firefox, loved you since version 0.6. :-( Hope there will be a workaround some day. – andreas Aug 30 '16 at 21:59
2

On Firefox 48 and above, this method doesn't work. Instead you should create two config files inside Firefox directory.

  1. Create config.js file in notepad (make sure file extension is .js and not .txt):

    //
    try {
    Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {})
    .eval("SIGNED_TYPES.clear()");
    }
    catch(ex) {}
    
  2. Move config.js to your Firefox installation directory:

    Windows: C:\Program Files\Mozilla Firefox
    (or C:\Program Files (x86)\Mozilla Firefox )

    Linux: /usr/lib64/firefox-< version >
    (or /usr/lib/firefox-< version > )

    Mac: /Applications/Firefox.app

  3. Create config-prefs.js in notepad:

    pref("general.config.obscure_value", 0);
    pref("general.config.filename", "config.js");
    
  4. Move config-prefs.js into Firefox defaults\pref directory.
    (e.g. C:\Program Files\Mozilla Firefox\defaults\pref)

  5. Restart Firefox.

  6. Drag the unsigned XPI into Firefox window, or use the "Install Add-on From File" option, in the settings of Firefox Add-ons.


Originate from this source: https://forum.mozilla-russia.org/viewtopic.php?id=70326

  • Unfortunately this method doesn't seem to work on FF 66.0.3 64-bit. It'd be sorely needed now that Mozilla has messed up BIG time. – CoolKoon May 4 '19 at 19:24
1

Apparently on Firefox 60 and above neither the xpinstall.signatures.required nor the config.js trick outlined above works (Mozilla, keel over please!).

The Russian forum that's referenced above apparently mentions a solution for these versions of Firefox as well. So put this into config.js instead which you then save to C:\Program Files\Mozilla Firefox

//
try {(code => {
    var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
    var jsval, evl = true, re = e => Cu.reportError(e), imp = name => {try {
        return Cu.import(`resource://gre/modules/addons/${name}.jsm`, {});
    } catch(ex) {}}
    if ((jsval = imp("AddonSettings"))) {
        jsval.AddonSettings = {ADDON_SIGNING: false, REQUIRE_SIGNING: false, ALLOW_LEGACY_EXTENSIONS: true};
        try {evl = jsval.eval("this") === jsval;} catch(ex) {evl = false;}
    }
    var jsvals = ["XPIProvider", "XPIInstall"].map(imp).filter(i => i);
    jsvals[0].AddonSettings && lockPref("extensions.allow-non-mpc-extensions", true);
    jsvals[0].signaturesNotRequired = true;

    if (evl) return jsvals.forEach(jsval => {try {jsval.eval(code);} catch(ex) {re(ex);}});

    var sl = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
    Cu.importGlobalProperties(["URL", "Blob"]); var url = URL.createObjectURL(new Blob([(code)]));
    jsvals.forEach(jsval => {try {sl.loadSubScript(url, jsval);} catch(ex) {re(ex);}});

})(String.raw`((vzss, pckg) => {
    var trueDesc = {enumerable: true, value: true};
    typeof Extension == "function" && Object.defineProperty(Extension.prototype, "experimentsAllowed", trueDesc);
    "AddonInternal" in this && Object.defineProperty(AddonInternal.prototype, "providesUpdatesSecurely", trueDesc);
    this.isDisabledLegacy = () => false;
    if ("XPIDatabase" in this) this.XPIDatabase.isDisabledLegacy = () => false;
    try {SIGNED_TYPES.clear();} catch(ex) {};

    if (!vzss && !pckg) return;

    var re = /\x06\x03U\x04\x03..(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)0\x82\x02"0\r\x06\t/i;
    var getUUID = () => {
        var gen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
        return (getUUID = () => gen.generateUUID().toString())();
    }
    var getIdFromString = str => {
        var match = str && str.match(re);
        return match ? match[1] : getUUID();
    }
    var getState = arg => ({
        signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED,
        cert: typeof arg == "object" ? arg : {commonName: arg}
    });
    var checkAddon = addon => {
        if (addon.id || (
            "_installLocation" in addon
                ? addon._installLocation.name == KEY_APP_TEMPORARY
                : addon.location.isTemporary
        ))
            return getState(null);
    }
    var getRoot = () =>
        !AppConstants.MOZ_REQUIRE_SIGNING && Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)
            ? Ci.nsIX509CertDB.AddonsStageRoot : Ci.nsIX509CertDB.AddonsPublicRoot;

    if (vzss) {
        var getURI = file => {
            var jsval = Cu.import("resource://gre/modules/addons/XPIProvider.jsm", {});
            return (getURI = file => jsval.getURIForResourceInFile(file, "META-INF/mozilla.rsa"))(file);
        }
        var getIdFromFile = file => {
            var str, is = {close() {}}, sis = {close() {}};
            try {
                is = Services.io.newChannelFromURIWithLoadInfo(getURI(file), null).open();
                sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
                sis.init(is);
                str = sis.readBytes(sis.available());
            } catch(ex) {}
            sis.close(); is.close();
            return getIdFromString(str);
        }
        this.verifyZipSignedState = function verifyZipSignedState(aFile, aAddon) {
            var res = checkAddon(aAddon);
            return res ? Promise.resolve(res) : new Promise(resolve => {
                var callback = {openSignedAppFileFinished(rv, zipReader, cert) {
                    zipReader && zipReader.close();
                    resolve(getState(cert || getIdFromFile(aFile)));
                }};
                gCertDB.openSignedAppFileAsync(getRoot(), aFile, callback.wrappedJSObject = callback);
            });
        }
    }

    if (pckg) Package.prototype.verifySignedState = function verifySignedState(addon) {
        var res = checkAddon(addon);
        return res ? Promise.resolve(res) : new Promise(resolve =>
            this.verifySignedStateForRoot(addon, getRoot()).then(({cert}) => {
                if (cert)
                    resolve(getState(cert));
                else
                    this.readBinary("META-INF", "mozilla.rsa").then(
                        buffer => resolve(getState(
                            getIdFromString(String.fromCharCode(...new Uint8Array(buffer)))
                        )),
                        () => resolve(getState(getUUID()))
                    );
            }, Cu.reportError)
        );
    }
})(
    "verifyZipSignedState" in this, typeof Package == "function"
);`)} catch(err) {
    err.message != "Components is not defined" && Components.utils.reportError(err);
}

Then you have to add this to the config-prefs.js file saved to C:\Program Files\Mozilla Firefox\defaults\pref

pref("general.config.obscure_value", 0);
pref("general.config.filename", "config.js");
pref("general.config.sandbox_enabled", false);

It's been tested to work on FF 66.0.3. Unfortunately it won't bring your addons and themes magically back, but at least it re-enables the option of re-installing them. Better than anything Mozilla has to offer anyway, as they don't seem to particularly care despite the fact that their forums are being flooded with complaints about this problem.

  • Look, if you really really want this, don't install random hacks, just use a Nightly where the signatures.required preference string is actually enabled. – Félix Saparelli May 5 '19 at 10:18
  • 1
    And why should I? Up until now I was completely fine with using what I thought to be stable versions of FF where I only installed legitimate and genuine addons straight from Firefox's official addon site. And now all these addons (and themes, for Christ's sake!) have stopped working all of a sudden. I'm sorry but instead of installing a potentially even more broken version of FF I prefer something that makes my current installation work instead. – CoolKoon May 5 '19 at 20:05
  • P.S. The addons have stopped working on the Android version of FF (v66.0.2) running on my phone as well, but curiously enough the xpinstall.signatures.required still seems to work there. – CoolKoon May 5 '19 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.