Bypassing the Firefox Addon Root Certificate
To jump ahead to the workaround, click here.If you are reading this article prior to 14 March 2025, you may have seen this rather ominous welcome page:
Readers after 14 March will notice that all their addons are disabled, with no way to re-enable or update them. Installation of new addons is also no longer possible:
As explained in rather vague terms here, a set of root certificates for verifying addons in Firefox expires on 14 March 2025. After the certificates expire, it will no longer be possible to run any of your addons at all (or at least, not any that were signed with that certificate). Some websites may not work as expected e.g. when playing DRM-enabled content.
Mozilla's only offered "solution" is to update Firefox to any version above 128.0. No alternatives have been given for those who cannot update. This is very bad news for those who need older versions of Firefox for legitimate reasons:
- People whose hardware only supports older versions of Mac (and thus only older versions of Firefox). Not everyone can afford to buy a new computer!
- Developers who use VMs to run addons or special configurations that no longer exist in modern versions of Firefox.
- Companies that rely on older Firefox versions for pure intranet or air-gapped setups (i.e. machines not connected to the internet). It may be impossible to update some of these legacy computers, even if their sysadmins want to.
In addition to the above, some people do not wish to update Firefox due to the almost inevitable loss of functionality. Mozilla has a very poor track record of removing or changing features of its browser without running proper A/B tests. Worse, Mozilla routinely ignores requests by users to reinstate even very simple features. Engineers make decisions about UI/UX with no oversight. There appears to be no good process for recovering from feature regressions at all.
And even if you do update? There is always the risk your user profile gets corrupted or settings are invisibly reverted.
In short: Mozilla's update pipeline is awful. And it leaves far too many users behind.
A Case of Bad Design
But wait! Why can't we just update the root certificate?
If you have any IT or software experience, you may have already tried to do this (and sadly, without success). After all, Firefox has a certificate manager in its settings menu; you can install, view, and reject certificates just fine using that. Some versions of Firefox can be coaxed into using OS certificates. And after all, the root certificate must be stored somewhere...right?
Unfortunately, this root certificate is hard-coded into Firefox's codebase.
To be more specific: the root certificate is bundled into Firefox's compiled code. Embedded into the atrociously named and absurdly oversized xul.dll. When every other certificate in Firefox has an external store/database, just like any other sane application handles it (even your OS!)—Mozilla placed the root certificate into its compiled code. Violating the magic number anti-pattern everyone is taught to avoid in Introduction to Python 101 (or Intro to Java, or Intro to C++, or whatever). As a result, the certificate cannot be updated or even removed without recompiling the entire application from source.
Yes.
How did this terrible design decision come about? A bit of history: Firefox experienced a very similar issue with expiration of the addon signing certificate back before 2020. This led to a wide panic culminating in a messy hotfix.
As a result of rushing the fix, Mozilla developers made the decision to hard-code the intermediate certificate directly into Firefox. That decision—which we developers call a workaround or hack—may well have made sense at the time. A lot of very angry people needed a fix for the broken certificate, and they needed it right away.
But as the saying goes: there is nothing more permanent than a temporary solution. A better approach for storing and updating the root certificate was never found (and as far as I can tell, was not even explored). This leads to the current predicament of 2025: the certificate is expiring again, and there is no easy way to update it.
Recompiling every old version of Firefox and redistributing these is obviously not an option. Mozilla is also unwilling to develop a patching tool to insert the new certificate into xul.dll (this also needs to be cross-tested across older Firefox versions, and developer time is expensive).
So we are left with a mess caused by a poor decision made 5 years ago, which was apparently never revisited or revised.
This is hardly a surprise to those of us who follow trends in software development. Mozilla, just like many other tech companies in 2025, has grown increasingly hostile towards any notion of user agency. The attitude: you do not own and have no control over any software you install. This may save a lot of money for companies (primarily by cutting QA and development costs), but it is a nightmare for the users of their products.
The Workaround
Thankfully, we can work around the certificate expiration by disabling the verification check for all addons. This will treat all addons as not needing to be signed.
WARNING: THIS WORKAROUND IS DANGEROUS! By disabling certificate verification, you can install any addon, even if it was not correctly signed. Malicious addons with invalid or spoofed signatures can make their way onto your browser and potentially your OS as well, installing malware, viruses, and other nasty things without your knowledge.
As such, I recommend applying this workaround only to systems with other security measures already in place e.g. sandboxed environments, VMs, air-gapped systems used only for viewing local files, and so on. I assume no responsibility if you get malware after applying this workaround. Browse safely and proceed with caution!
Note: in Firefox 48 and thereabouts, you may not need to perform this workaround. It is possible to set xpinstall.signatures.required = false
in about:config
as described here (that page also provides other fixes for some older Firefox versions). This setting still exists in modern Firefox versions, but was effectively disabled by the Mozilla developers due to "concerns it might be abused". If Mozilla had stored its certificates properly, we wouldn't need such settings!
This workaround only fixes disabled addons. Websites that have stopped working correctly due to the certificate expiration (including DRM-protected content) cannot be fixed.
1. Restore any disabled addons:
This workaround will prevent your addons from being disabled, but will not always bring them back if already disabled (due to how Firefox caches the verification status).
To fix this, you must first set the system date to anything prior to 14 March 2025. I recommend that you also disable internet time sync on your OS to prevent the changed time from reverting. On Windows, this looks like the following:
After setting the date, open Firefox and go to your addons menu. Any disabled addons will re-enable themselves after a moment (this can take up to a minute if you have a lot of them). Sometimes you need to close and reopen Firefox once or twice for this to work.
Close Firefox and do not open it again until this guide instructs you to do so.
Finally, reset your system time and enable internet sync if you disabled it previously.
2. Back up omni.ja:
The file we are going to modify is called omni.ja. It is found in your Firefox installation folder (for Windows, this is usually C:\Program Files\Mozilla Firefox
). Mac users will need to open the Firefox application bundle before they can view this file (see here for instructions).
Back up the file e.g. by copying it and renaming it to omni.ja.BAK:
If you don't create a backup, your Firefox installation will be permanently corrupted if you make any mistakes in the following steps!
3. Open omni.ja:
The file omni.ja is really just a ZIP archive. Copy it to your desktop and open it with WinRAR or 7zip. You can also rename it with a .zip extension to open it with your default program (just make sure you change the extension back afterwards).
On Windows, make sure you copy the file onto your desktop first! You won't be able to edit or save it from within the Program Files directory.
Within omni.ja, navigate to modules/addons
and extract the XPIInstall.jsm file to your desktop:
Different versions of Firefox may name this file differently. You can usually find the correct one with a bit of trial-and-error (see the next step if this applies to you).
4. Remove the verification function:
Open XPIInstall.jsm (or the file you extracted) with a text editor and search for the text string verifySignedState
. You should be directed to a function somewhat like the following:
async verifySignedState(addonId, addonType, addonLocation) { if (!shouldVerifySignedState(addonType, addonLocation)) { return { signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED, cert: null, }; } let root = Ci.nsIX509CertDB.AddonsPublicRoot; if ( !AppConstants.MOZ_REQUIRE_SIGNING && Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false) ) { root = Ci.nsIX509CertDB.AddonsStageRoot; } return this.verifySignedStateForRoot(addonId, root); }
If you cannot find this function, try searching for SIGNEDSTATE
as displayed above. For older Firefox versions, this function may be in a different file such as XPIProvider or AddonSettings. Keep extracting and searching until you find the right one.
Once you have found the correct function, prepend every line in the function with comments //
like so, leaving the SIGNEDSTATE_NOT_REQUIRED
return statement unchanged:
async verifySignedState(addonId, addonType, addonLocation) { //if (!shouldVerifySignedState(addonType, addonLocation)) { return { signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED, cert: null, }; //} //let root = Ci.nsIX509CertDB.AddonsPublicRoot; //if ( // !AppConstants.MOZ_REQUIRE_SIGNING && // Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false) //) { // root = Ci.nsIX509CertDB.AddonsStageRoot; //} //return this.verifySignedStateForRoot(addonId, root); }
The comments are basically telling the application "ignore this line", so you can can also just replace the function entirely like so. The result will be the same either way:
async verifySignedState(addonId, addonType, addonLocation) { return { signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED, cert: null, }; }
After changing the function, save the file and reinsert it into omni.ja (on your desktop). Save the archive as needed; most tools automatically save whenever you reinsert a file.
Move the modified omni.ja back into your Firefox installation directory, overwriting the file that is already there (you did back up the file first, right?).
5. Open Firefox:
After moving the modified omni.ja to your installation folder, open Firefox and wait for a few seconds. Then check your addons menu to see if any addons have been disabled. If they haven't—congratulations! You have successfully bypassed the certificate verification check.
If your addons still got disabled, repeat Step 1 to restore them, then verify that you commented out the right function/file and that the modified omni.ja was correctly copied into the application folder. Depending on your Firefox version, it may take some trial-and-error to get this working—but once you do, you won't need to worry about it ever again.
FAQ
Can I install new addons after applying this workaround?
No, this is very unsafe!
The official repository for Firefox addons likely won't permit you to install anything after 14 March 2025 regardless of this workaround. Even if it does, there is no way for you to verify whether the addon signer is legitimate. Trying to install new addons with this workaround applied opens you to man-in-the-middle attacks.
If you absolutely must install a new addon, do so only in Firefox 128 or later. You may be able to copy the installed addon back into your older Firefox version, but only if the two applications are already very close in version. Those who have sandboxed Firefox properly e.g. in a VM may be able to install addons, but should still apply caution.
Can I update my current addons after applying this workaround?
No, this is not safe either!
Every time you update an addon, you are trusting the author and Mozilla to deliver the right file to you. If Mozilla or the author are hacked or experience any other security breach, it is possible for the attacker to deliver a malicious addon to your browser. In other words—without the new root certificate, you cannot know if your addon is being updated to the right thing.
Can't I just keep the system date set before 14 March 2025?
This is a bad idea for anything other than short-term debugging. Many websites and even local applications will not work if you have a system date set to anything other than the current date. Licensed and DRM-protected applications may stop working entirely. Your entire computer and any connected peripherals may behave strangely—even some printers, strangely enough!
Setting the system clock back as a way of installing addons is a very bad idea and does not usually work anyways.
Can't I just recompile Firefox to insert the new certificate?
If you want to? Go for it!
However, be warned: Mozilla's build system is an utter mess. Although you can download source code for any version of Firefox, the official tools for building Firefox only work with the most recent version.
From my own experience, it is almost impossible to build earlier versions of Firefox with these tools unless you have exactly the same development environment as the original builder. This effectively makes the source code useless, since you can't really do anything with it. Be ready for an onslaught of obscure C++ errors that can only be fixed by having a very specific toolchain with very specific compilation flags (none of which are documented in the source code release). Even getting MozillaBuild to recognize a specific Firefox version can be tricky.
Don't believe me? The current release of MozillaBuild (4.1), released two months ago, is still 100% broken. It is impossible to build Firefox using this version due to a change in subprocess.py
(4.1 updated the packaged Python version to 3.11). Because MozillaBuild uses its own tools rather than your system-installed ones, there is no way that 4.1 ever worked as tested from scratch in an empty environment. The developers never tested their code!
Worse, the same bug that prevents 4.1 from working has occurred at least twice before. In a rare moment of good practice, Mozilla added these bug numbers directly in the source code for future reference. However, they didn't actually test for this bug before pushing the application to release, nor did they create unit tests to prevent it from occurring again.
In short: Mozilla's developers push new tools without testing them. This is a violation of the most basic tenets of version control, and Mozilla doesn't even care.
Even if you do get all the build tools working, building Firefox still proves a nightmare. You need 40 gigabytes of disk space for a full compilation, with some reporting build times exceeding two hours even on fast machines. That means if you make even one little mistake in C++, you may need to wait another two hours just to test whether you actually fixed it.
The file into which the root certificate is compiled (xul.dll on Windows) is almost 120 MB. This is more than twice the size of a typical AAA game .exe, with all bundled DLLs, combined (as a reminder, DLLs and EXEs represent compiled code, which is supposed to be small). In fact, as of this writing, my copy of IDA Pro—which normally decodes DLLs in a matter of minutes—was still working on decoding xul.dll after 24 straight hours of operation.
How can a browser need so much darned code?
If I haven't scared you off, then have at it! Just make sure you submit any bugs you encounter to https://bugzilla.mozilla.org—not to me.