我如何禁用Firefox插件的签名检查?

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

1
欢迎回来(2019年5月) - neverMind9
7个回答

45

10
现在Chrome之后,Firefox也要求我安装开发者版本才能进行正常浏览或将我的扩展程序改为TamperMonkey脚本。顺便问一下,这是某种眼镜蛇效应的问题吗? - Gustavo Rodrigues
似乎选项现在也在“常规”Firefox版本中可用(在45.0.1上进行了检查;不确定它是何时出现的)。 - Janaka Bandara
@Makyen Firefox 44封锁未验证的插件,但可以在“about:config”中将设置“xpinstall.signatures.required”设置为“false”。 - Maelkum
@Mael,是的,在FF44中,“xpinstall.signatures.required=false”可行。它适用于FF <=47.0.1。在FF48.0b10和48.0中不起作用。我对这个答案的问题是,尽管已经发布了一年,它仍然是不准确的。明天,一旦FF48在发布频道上发布,它将最终变得准确。虽然这个问题是一个动态目标,但我个人认为在回答中提供准确的信息是有义务的,特别是那些被高度赞同的答案。尽管这个答案得到了很多声誉,但OP拒绝使它准确(说发布和beta是可能的<FF48)。 - Makyen
4
明确表示,在标准版本的Firefox中(至少在51.01版本上),可以切换选项xpinstall.signatures.required,但这没有任何效果。插件仍然需要一个签名。 - joelostblom
显示剩余7条评论

25

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

Firefox版本65+(或更高)

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

如果在about:config中将javascript.enabled设置为False,则此代码将无法运行。该选项需要设置为True,这是默认设置。

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

我已在Firefox 66.0.3+上进行了测试。

升级版本的过程似乎会在不激活这些更改的情况下暂时运行浏览器代码。因此,当您第一次运行新版本的Firefox时,依赖于禁用附加组件签名的安装的任何扩展都将被禁用。您可以在升级到新的Firefox版本后立即重新安装这些扩展,扩展应该可以继续工作。
我记得,对于Firefox 65,需要一些稍微不同的代码,我相信当我为Firefox 66修改它时,我将那段代码留在了disable-add-on-signing.js中,但我不确定。
我们将使用一种技术,允许您从存储在Firefox配置文件目录中的文件中在浏览器上下文中运行任意JavaScript代码。我从Haggai Nuchi的GitHub存储库:Firefox Quantum兼容的userChrome.js中找到了如何做到这一点。
在Windows上,您的Firefox配置文件目录将是%appdata%\Mozilla\Firefox\Profiles\[profileID]。如果您只有一个配置文件,[profileID]将是%appdata%\Mozilla\Firefox\Profiles目录中唯一的目录。如果您有多个配置文件,您需要选择要将此修改安装到的配置文件。
一旦你进入你的个人资料目录,如果还不存在的话,你需要创建一个名为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(与Haggai Nuchi的GitHub存储库中可用的版本略有不同):
<?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。您可以通过在浏览器控制台中查找“附加组件签名已禁用。”来验证代码是否正在运行。
被Firefox禁用或移除的附加组件将不会自动启用。您需要重新安装它们。您可以通过将*.xpi文件拖放到Firefox窗口上并确认您要安装来安装它们。
如果您想从Mozilla附加组件获取任何特定扩展的*.xpi文件,您可以右键单击“安装”按钮,然后选择“另存为”或“移除”来下载它。

Firefox 57或更早版本

不幸的是,我不记得这个方法停止工作的Firefox版本是哪个。我知道我在Firefox 54、55、52ESR和FF56.*上使用过它。
我最初是在这篇博客文章中找到了禁用强制附加组件签名检查的解决方案,这也是这个答案中代码的原始来源(稍作修改)。通过进行这些更改,您可以使用您修改的Firefox分发版本将未签名的附加组件安装到配置文件中。对于大多数人来说,这将是您的主要Firefox安装。但是,如果您安装了多个版本,您需要在每个安装中进行此修改。然而,一旦您进行了修改,它们将通过正常的Firefox更新保留下来。
您需要在Firefox安装目录中添加一些文件。您可以在mozillaZine上找到Windows、Linux和Mac OS的安装目录示例列表。最常见的安装目录有:
  • Windows
  • C:\Program Files\Mozilla Firefox\
  • C:\Program Files (x86)\Mozilla Firefox\
  • Linux
  • /usr/lib/firefox-<version>
  • OSX
  • /Applications/Firefox.app

添加第一个文件

你需要将以下代码添加到文件<安装目录>/defaults/pref/disable-add-on-signing-prefs.js中(Windows: <安装目录>\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");

添加第二个文件

您还需要将以下代码添加为文件<安装目录>/disable-add-on-signing.js(Windows: <安装目录>\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) {}

结果

多年来,我一直使用这些解决方案来安装我自己开发的一些扩展,并测试我正在开发的扩展的新版本(当我想要在发布版本中进行测试而不是Firefox开发者版夜间版时)。

注意:about:addons中,Firefox在某些情况下可能会显示扩展已启用(未灰掉),但会显示扩展“无法验证并已禁用”的文本。这个文本是不准确的!扩展是已启用并正常运行的。

工作原理

resource://gre/modules/addons/XPIProvider.jsm中,const SIGNED_TYPES被定义为一个Set。为了使插件需要签名,其类型必须是该Set的成员。Set.prototype.clear()方法用于清除Set中的所有条目。这将导致不需要签名的插件类型(代码1代码2)。

如果你想的话,你可以分别禁用以下任何类型的签名检查:"webextension""extension""experiment""apiextension"

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

上述部分中的附加文件关闭了扩展必须签名的要求。如果签名文件存在,签名仍将被验证。因此,如果你修改了一个已签名的扩展,并且没有删除签名文件,该扩展将无法通过签名验证。换句话说,实际检查现有签名是与签名必须存在的要求分开的步骤。
如果你修改了一个已签名的扩展(你可以通过扩展根目录中存在META-INF目录来判断),那么你需要删除签名文件。你可以通过删除META-INF目录及其包含的所有文件来实现。

1. 博客中的代码将此调用放在一个try{}catch(){}块中。实际上没有必要这样做。这样做的唯一有效作用是防止任何错误在浏览器控制台Ctrl-Shift-J,或者在OSX上是Cmd-Shift-J)中报告。如果此操作失败,没有其他代码需要运行。此外,如果此操作失败,我希望能在浏览器控制台中看到错误,以便知道它确实失败了。不使用try{}catch(){}没有任何负面影响,并且可以追踪问题,如果在未来的Firefox版本中,插件因未签名而被禁用。


@WalterGR,我已更新此答案以包括从修改的扩展中删除META-INF目录及其内容的需要。正如我在添加的文本中提到的那样,实际的签名检查是与通过签名存在的要求分开的步骤。警告“文件不正确”是指扩展中的一个或多个文件与存储在META-INF目录中的文件中的校验和不匹配且经过加密签名。 - Makyen
1
当我把文件放到相应的目录中时,Firefox 在启动时崩溃,并显示“无法读取配置文件”的消息。已在 Firefox 59.0.1 上进行了测试。 - niceman
1
@AaA Firefox 54.0现在非常老了。我知道我曾经在FF54、FF55、FF52ESR和FF56.*中使用过它。因此,我有点惊讶会出现问题。我注意到我为了FF55的兼容性,在disable-add-on-signing.js中添加了XPIInstall.jsm行。因此,可能需要删除该行。我不记得在进行这些更改后是否在FF54上再次测试过它。请注意,有时插件页面似乎表明它没有工作,而实际上它确实工作,你需要重新安装先前禁用的插件。 - Makyen
1
@dbc 有趣。谢谢你的提醒。这真是好知道啊。我本来没想到那个配置选项会禁用以这种方式加载的 JavaScript。我原本以为该选项只适用于从网页中加载的 JavaScript,而不适用于浏览器上下文中的引用。然而,经过测试,当 javascript.enabled 设置为 false 时,它确实被禁用了。 - Makyen
1
我尝试了针对Firefox 56版本的解决方案。它完美地运行。它也适用于便携式版本。 - SJ9
显示剩余17条评论

6
为了补充上面的答案,我发现了firefox-autoconfig,它由在<FIREFOX INSTALLATION DIR>/default/prefs中安装一个autoconfig.js文件和在<FIREFOX INSTALLATION DIR>中安装一个ci.clg文件组成。这是一种在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);

4

自Firefox 47版本开始:Firefox桌面版的发布版和Beta版将不允许安装未签名的扩展,没有任何覆盖选项。

更多信息请参见Mozilla关于扩展签名的Wiki页面


2

@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中被标记为已禁用,但实际上是活动的(您可以像普通插件一样手动禁用/启用它)。

其工作原理如下:

  • mustSign()检查是否需要对此类型的插件进行签名。

  • verifySignatures()是一个回调函数,用于每XPI_SIGNATURE_CHECK_PERIOD秒(即每天一次)检查签名。


1
我发现了一个更简单的方法,似乎有效,就是翻转Firefox用来确定是否强制签名的常量。这可能需要在每次Firefox更新后进行。
  1. 在你的Firefox安装目录中找到omni.ja文件
  2. 将该文件解压缩为一个工作文件夹中的zip文件
  3. 使用文本编辑器编辑modules/AppConstants.jsm,并将MOZ_REQUIRE_SIGNING下的值从true改为false
  4. 将修改后的内容重新压缩到omni.ja
  5. about:config下验证xpinstall.signatures.requiredxpinstall.whitelist.required的值是否为false,并重新启动Firefox

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


如果更改了omni.ja文件,Firefox 65+会崩溃。 - hldev
如果您正确地解压/重新打包omni.ja文件,则Firefox不会崩溃。如果您尝试像普通zip文件一样编辑/替换文件,则不能保证。发布此答案时,Firefox 80系列版本是当前版本。 - xperia64
1
https://web.archive.org/web/20210531175757/https://developer.mozilla.org/en-US/docs/Mozilla/About_omni.ja_(formerly_omni.jar) 上说:“打包 omni.ja 的正确命令是:zip -0DXqr omni.ja *”。但是你可以将那个 0 改成 9 来启用实际压缩。 - biziclop
你的回答帮了我很多。存档 C:\Program Files\Mozilla Firefox\omni.ja 没有被压缩,所以你可以跳过重新打包的步骤。只需在类似于 https://chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm 的十六进制编辑器中进行编辑,找到字符串 MOZ_REQUIRE_SIGNING:  true 的第一个出现,并将其覆盖为 MOZ_REQUIRE_SIGNING: false(保持文件大小不变)。然后通过命令行重新启动浏览器以应用更改。使用以下命令:"C:\Program Files\Mozilla Firefox\firefox.exe" --purgecaches https://superuser.com/a/1536420/1194827 现在你可以(重新)安装(拖放)未签名的 .xpi 插件。 - Stano

1

我在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访问。它会立即重新启用所有未通过验证的插件。


注意:使用 async / await 需要 Firefox 52+。此外,在 浏览器控制台 中输入命令行需要在 about:config 偏好设置中启用 (devtools.chrome.enabled 必须为 true) 或在开发者工具设置中选择 "启用浏览器 chrome 和附加组件调试工具箱" 选项 (FF40+)。 - Makyen
对我来说,在Firefox 55.0.3上运行良好。值得一提的是,更改是否持久以及插件是否会在下次每日签名检查或下次启动Firefox时再次禁用。 - Maëlan
@Maëlan 我自己正在使用这种方法。到目前为止,插件似乎可以正常工作,所以很难评判。我怀疑它不是持久的。 - Athari
我的插件又被禁用了,尽管自上次发生此事以来我并没有重新启动 Firefox,因此我确认此修复的效果是暂时的。我只需重新运行这段代码,所以不用担心,前提是 Mozilla 快点修复过期的证书。否则... - Maëlan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接