如何禁用 Firefox 附加组件的签名检查?

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

自版本 42 起,Firefox 默认拒绝安装未签名的附加组件。如何禁用此验证?

只能在Nightly and Developer频道中禁用插件验证。换句话说,在 Beta 版本和标准版本中是不可能的

  1. 转到about:config(在地址栏中输入)
  2. xpinstall.signatures.required 设置为 false

更多信息在 https://wiki.mozilla.org/Addons/Extension_Signing

为了完成上述答案,我发现 firefox-autoconfig,包括在 <FIREFOX INSTALLATION DIR>/default/prefs 中安装一个 autoconfig.js 文件和一个 [= <FIREFOX INSTALLATION DIR> 中的 14=] 文件,这是一种在打开 Firefox 时明确和自动地禁用 xpinstall.signatures.required (以及其他选项)的方法(使用 Firefox 45.0.1 测试)

您将在autoconfig.js中看到这些内容:

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

以及ci.cfg中的那些内容:

// Disable checking if firefox is default browser
lockPref('browser.shell.checkDefaultBrowser', false);

// Disable restoring session
lockPref('browser.sessionstore.resume_from_crash', false);

// Disable extension signature check
lockPref('xpinstall.signatures.required', false);

// Allow extensions to be installed without user prompt
pref("extensions.autoDisableScopes", 0);
pref("extensions.enabledScopes", 15);

// Disable updater
lockPref("app.update.enabled", false);
// make absolutely sure it is really off
lockPref("app.update.auto", false);
lockPref("app.update.mode", 0);
lockPref("app.update.service.enabled", false);

// Prevent closing dialogs
lockPref("browser.showQuitWarning", false);
lockPref("browser.warnOnQuit", false);
lockPref("browser.tabs.warnOnClose", false);
lockPref("browser.tabs.warnOnCloseOtherTabs", false);

// Disable Add-ons compatibility checking
clearPref("extensions.lastAppVersion");

// Don't show 'know your rights' on first run
pref("browser.rights.3.shown", true);

//Disable plugin checking
lockPref("plugins.hide_infobar_for_outdated_plugin", true);
clearPref("plugins.update.url");

// Disable health reporter
lockPref("datareporting.healthreport.service.enabled", false);

// Disable all data upload (Telemetry and FHR)
lockPref("datareporting.policy.dataSubmissionEnabled", false);

// Disable crash reporter
lockPref("toolkit.crashreporter.enabled", false);
Components.classes["@mozilla.org/toolkit/crash-reporter;1"].getService(Components.interfaces.nsICrashReporter).submitReports = false;

// Browser Console command line
pref("devtools.chrome.enabled", true);

从 Firefox 47 开始:桌面版 Firefox 的发行版和 Beta 版将不允许安装未签名的扩展,没有覆盖。

有关详细信息,请参阅 Mozilla Wiki page on Extension Signing

在发布(所有)版本的 Firefox 中禁用附加组件签名检查

Firefox 版本 65+(或左右)

以下说明将禁用 Firefox 上安装文件的 Firefox 配置文件的签名检查。您将向 Firefox 配置文件目录下的 chrome 目录添加一些文件。

如果 javascript.enabledabout:config 中设置为 False,则此代码将不起作用。该选项需要设置为 True,这是默认设置。

从 Firefox 69+ 开始,除了下面的说明之外,您还需要在 about:config 中将 toolkit.legacyUserProfileCustomizations.stylesheets 设置为 true。如果它不存在,那么您将需要创建它("new" 在右键单击上下文菜单中)作为布尔选项。有关添加此选项的更多详细信息,请参阅 Bugzilla 1541233

我已经在 Firefox 66.0.3+ 上测试过了。

升级版本的过程似乎短暂地 运行 具有这些更改的浏览器代码未激活。因此,当您第一次 运行 新版本的 Firefox 时,您安装的任何依赖于禁用附加组件签名的扩展都将被禁用。升级到新的 Firefox 版本后,您可以立即重新安装这些扩展,扩展应该会恢复工作。

IIRC,Firefox 65 需要一些稍微不同的代码,我相信我在修改它时将代码留在 disable-add-on-signing.js 中Firefox 66,但我不确定。

我们将使用一种技术,允许您从存储在 Firefox 配置文件目录中的文件中 运行 浏览器上下文中的任意 JavaScript 代码。我从 Haggai Nuchi's GitHub repository: Firefox Quantum compatible userChrome.js 中找到了如何执行此操作。

在 Windows,您的 Firefox 配置文件目录将为 %appdata%\Mozilla\Firefox\Profiles\[profileID]。如果您只有一个配置文件,[profileID] 将是 %appdata%\Mozilla\Firefox\Profiles 目录中的唯一目录。如果您有多个配置文件,则需要 select 您想要安装此 hack 的那个。

进入个人资料目录后,您需要创建一个名为 chrome 的目录(如果尚不存在)。您需要将以下 3 个文件添加到该目录:

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

然后您将需要 userChrome.css 中的以下代码,可从 Haggai Nuchi 的 GitHub 存储库中获得:

/*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");
}

您将需要 userChrome.xml(从 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>

您还需要 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.');

将这些文件添加到配置文件的 chrome 目录后,您需要重新启动 Firefox。您可以通过在 Browser Console.

中查找 "Add-on signing disabled." 来验证代码是否为 运行ning

被 Firefox 禁用或删除的附加组件不会自动启用。您将需要重新安装它们。您可以通过将 *.xpi 文件拖放到 Firefox window 并确认您要安装来安装它们。

如果您想从 Mozilla Add-ons 获取任何特定扩展名的 *.xpi 文件,您可以通过右键单击 "install" 按钮并 selecting "Save As",或 "Remove"。

Firefox 版本 57 或更早版本(左右)

不幸的是,我不记得此方法在哪个版本的 Firefox 上停止工作。我知道我在 Firefox 54、55、52ESR 和 FF56.*.

上使用它

我最初在 this blog post 中找到了禁用强制附加签名检查的解决方案,这是此答案中(稍作修改的)代码的原始来源。进行这些更改将允许您使用您修改的 Firefox 发行版将未签名的附加组件安装到配置文件中。对于大多数人来说,这将是您的主要 Firefox 安装。但是,如果您安装了多个版本,则需要在每次安装时都进行此修改。但是,一旦您进行了修改,它们将通过正常的 Firefox 更新保留。

您需要在 Firefox 安装目录中添加几个文件。你可以找到一个list of installation directory examples for Windows, Linux, and Mac OS on mozillaZine。最常见的安装目录是:

  • Windows
    • C:\程序Files\Mozilla火狐\
    • C:\Program Files (x86)\Mozilla Firefox\
  • Linux
    • /usr/lib/firefox-<版本>
  • OSX
    • /Applications/Firefox.app

添加第一个文件

然后您需要添加下面的代码作为文件 <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");

添加第二个文件

您还需要添加以下代码作为文件 <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) {}

结果

多年来我一直在使用这些解决方案来安装一些我为自己使用而构建的扩展,并测试我正在开发的扩展的新版本(当我想在 Release version instead of Firefox Developer Edition or Nightly).

注意:about:addons Firefox 中 可能 显示(在某些情况下)附加组件已启用(未变灰-out),但有文字说明附加组件 "could not be verified and has been disabled"。文字不准确!加载项已启用并正常运行。

工作原理

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 内)。

如果您愿意,可以单独禁用任何类型的签名检查:"webextension""extension""experiment""apiextension"

从任何修改后的扩展中删除 META-INF 目录

以上部分中的附加文件关闭了扩展 必须 签名的 要求。如果签名文件存在,仍然会验证签名。因此,如果您修改了一个已签名的扩展名并且没有删除签名文件,则该扩展名将无法通过签名验证。换句话说,实际检查任何现有签名是与签名必须存在的要求分开的步骤。

如果您修改了一个已签名的扩展(您可以通过扩展根目录中存在的 META-INF 目录判断它已被签名),那么您将需要删除签名文件。您可以通过删除 META-INF 目录和该目录中包含的所有文件来执行此操作。


1.博客中的代码将此调用放在 try{}catch(){} 块中。真的没有必要这样做。这样做唯一有效的做法是防止在 Browser Console (Ctrl-Shift-J,或 Cmd-Shift-J on OSX).如果失败,则没有其他代码需要 运行。此外,如果失败,我希望能够在浏览器控制台中看到错误,以便知道它实际上已经失败了。没有 try{}catch(){} 不会有任何负面影响,并且如果在某些未来版本的 Firefox 上,加载项由于未签名而开始被禁用,则允许追踪问题。

@Makyen 的解决方案有效,但会完全禁用签名检查:

Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {})
      .eval("SIGNED_TYPES.clear()");

不会知道插件是否已签名。

相反,我建议这样做:

/* Let unsigned addons live! */
Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {})
          .eval("function mustSign(aType) { return false; }");
Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {})
        .eval("XPIProvider.verifySignatures = function() {}");

当您尝试安装未签名的插件时,它仍会警告您,但它仍然可以运行。该插件在 about:addons 中被标记为禁用,但实际上处于活动状态(您可以 disable/enable 它像普通插件一样手动)。

工作原理:

  • mustSign() 检查是否需要签名这种类型的插件。

  • verifySignatures() 是用于每 XPI_SIGNATURE_CHECK_PERIOD 秒(即每天一次)检查签名的回调

这是我在 thread on HackerNews 中找到的关于附加签名启示录的代码。它可以在 Firefox 56 和旧版本中运行而无需重新启动。

  // For FF < v57 >...?
  async function set_addons_as_signed() {
      Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm");
      Components.utils.import("resource://gre/modules/AddonManager.jsm");
      let XPIDatabase = this.XPIInternal.XPIDatabase;

      let addons = await XPIDatabase.getAddonList(a => true);

      for (let addon of addons) {
          // The add-on might have vanished, we'll catch that on the next startup
          if (!addon._sourceBundle.exists())
              continue;

          if( addon.signedState != AddonManager.SIGNEDSTATE_UNKNOWN )
              continue;

          addon.signedState = AddonManager.SIGNEDSTATE_NOT_REQUIRED;
          AddonManagerPrivate.callAddonListeners("onPropertyChanged",
                                                  addon.wrapper,
                                                  ["signedState"]);

          await XPIProvider.updateAddonDisabledState(addon);

      }
      XPIDatabase.saveChanges();
  }

  set_addons_as_signed();

此代码需要在浏览器控制台(而非 网络控制台)中执行,可以通过快捷键 Ctrl+Shift+J。它会立即重新启用所有未通过验证的插件。

我发现一种似乎有效的更简单方法是翻转 Firefox 用来确定是否强制签名的常量。这可能需要在每次 Firefox 更新后完成。

  1. 在您的 Firefox 安装目录中找到 omni.ja 存档
  2. 将此文件作为 zip 存档解压缩到工作文件夹
  3. 在您的文本编辑器中编辑 modules/AppConstants.jsm,并将 MOZ_REQUIRE_SIGNING 下的值从 false 更改为 true
  4. 将修改后的内容重新压缩回omni.ja
  5. about:config下验证xpinstall.signatures.requiredxpinstall.whitelist.required为false,重启firefox

你未签名的插件现在应该安装了。