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.
2Fantastic! This fix will suffice until EFF and others have there extensions verified. – VitaminYes – 2015-08-12T21:02:29.083
1This also won't work after version 43+. :( – Suresh Atta – 2016-08-06T19:47:55.490
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 – 2016-08-09T13:51:17.847
@ThatBrazilianGato: is is not working for me on Win7 FF48.0 :( – glavić – 2016-08-16T13:37:42.827
In release notes for FF 48.0 it says: Add-ons that have not been verified and signed by Mozilla will not load
– glavić – 2016-08-16T13:41:08.343Firefox 48: (Pushed from Firefox 46). Release and Beta versions of Firefox for Desktop will not allow unsigned extensions to be installed, with no override. Firefox for Android will enforce add-on signing, and will retain a preference — which will be removed in a future release — to allow the user to disable signing enforcement. – glavić – 2016-08-16T13:42:51.263
4That's it for me. Bye Firefox, loved you since version 0.6. :-( Hope there will be a workaround some day. – andreas – 2016-08-30T21:59:18.183
Firefox has been known for its crazy amount of malicious add-ons over which it seems to have little control. For a basic user, it becomes a nightmare. For a tech person, it becomes an oft-vanquished enemy. – Arlen Beiler – 2017-07-11T20:14:51.890