最近在 Firefox 中禁用附加组件的技术细节

笔记译者:为了方便读者,日期为莫斯科时间

我们最近错过了用于签署附加组件的证书之一的到期时间。 这导致用户无法使用附加组件。 现在问题已经基本解决,我想分享一下所发生的事情和所做的工作的细节。

背景:补充和签名

尽管许多人直接使用该浏览器,但 Firefox 支持称为“附加组件”的扩展。 在他们的帮助下,用户可以向浏览器添加各种功能。 有超过 15 个附加组件: 广告拦截管理数百个选项卡.

安装的附加组件必须有 电子签名,它可以保护用户免受恶意加载项的侵害,并且需要 Mozilla 员工对加载项进行最少的审查。 我们于 2015 年引入了此要求,因为我们遇到了 严重问题 带有恶意插件。

工作原理:每个 Firefox 副本都包含一个“根证书”。 这个“根”的密钥存储在 硬件安全模块 (HSM)无需网络访问。 每隔几年,就会使用此密钥签署一个新的“中间证书”,该密钥在签署附加组件时使用。 当开发人员提交附加组件时,我们会创建一个临时“最终证书”并使用中间证书对其进行签名。 然后使用最终证书对附加组件本身进行签名。 示意性地 看起来像这样.

请注意,每个证书都有一个“主题”(证书的颁发者)和“颁发者”(证书的颁发者)。 对于根证书,“subject”=“issuer”,但对于其他证书,证书的颁发者是其签名的父证书的主题。

重要的一点:每个附加组件都由唯一的最终证书签名,但这些最终证书几乎总是由相同的中间证书签名。

作者注:例外是非常旧的添加内容。 当时使用的是各种中级证书。

这种中间证书带来了问题:每个证书都有一定的有效期。 在此期限之前或之后,证书无效,浏览器将不会使用由该证书签名的加载项。 不幸的是,中级证书于4月4日凌晨XNUMX点到期。

后果并没有立即显现。 Firefox 不会持续检查已安装附加组件的签名,而是大约每 24 小时检查一次,并且每个用户的验证时间都是单独的。 结果,有些人立即遇到问题,而另一些人则晚得多才遇到问题。 我们在证书过期时首次意识到该问题,并立即开始寻找解决方案。

减少伤害

一旦我们意识到发生了什么事,我们就尽力防止情况变得更糟。

首先,他们停止接受和签署新的补充。 为此使用过期的证书是没有意义的。 回顾过去,我想说我们本可以让一切保持原样。 我们现在已经恢复接受补品。

其次,他们立即发布了修复程序,阻止每天检查签名。 因此,我们保留了那些在过去 XNUMX 小时内浏览器还没有时间检查附加组件的用户。 此修复现已撤回,不再需要。

并联运行

理论上,该问题的解决方案看起来很简单:创建一个新的有效中间证书并重新签署每个附加组件。 不幸的是,这行不通:

  • 我们无法一次快速重新签署 15 个附加组件,该系统不是为这样的负载而设计的
  • 在我们签署添加内容后,需要将更新的版本交付给用户。 大多数附加组件都是从 Mozilla 服务器安装的,因此 Firefox 将在接下来的 XNUMX 小时内找到更新,但一些开发人员通过第三方渠道分发签名附加组件,因此用户必须手动更新此类附加组件

相反,我们尝试开发一种修复程序,无需用户采取太多操作或无需采取任何操作,即可覆盖所有用户。

很快我们就得出了两个并行使用的主要策略:

  • 更新 Firefox 以更改证书有效期。 这将使现有的附加组件再次神奇地工作,但需要发布和发布新版本的 Firefox
  • 生成一个有效的证书并以某种方式说服 Firefox 接受它而不是已过期的现有证书

我们决定首先使用第一个选项,它看起来相当可行。 最终,他们发布了第二个修复程序(新证书),我们稍后会讨论。

更换证书

正如我上面提到的,需要:

  • 创建新的有效证书
  • 在 Firefox 中远程安装

为了理解为什么会这样,让我们​​仔细看看附加组件验证过程。 该附加组件本身作为一组文件提供,包括用于签名的证书链。 因此,如果浏览器知道根证书(在构建时内置于 Firefox 中),则可以验证该附加组件。 但是,正如我们所知,中间证书已过期,因此无法验证该附加组件。

当 Firefox 尝试验证附加组件时,它不仅限于使用附加组件本身包含的证书。 相反,浏览器会尝试创建有效的证书链,从最终证书开始一直持续到根证书。 在第一级,我们从最终证书开始,然后找到主体为最终证书(即中间证书)的颁发者的证书。 通常,此中间证书随附加组件一起提供,但浏览器存储中的任何证书也可以用作此中间证书。 如果我们可以远程将新的有效证书添加到证书存储中,Firefox 将尝试使用它。 安装新证书前后的情况.

安装新证书后,Firefox 在验证证书链时将有两个选项:使用旧的无效证书(不起作用)或新的有效证书(将起作用)。 重要的是,新证书包含与旧证书相同的主题名称和公钥,因此它在最终证书上的签名将有效。 Firefox 足够聪明,可以尝试这两种选项,直到找到一种有效的选项,因此插件会再次经过测试。 请注意,这与我们用于验证 TLS 证书的逻辑相同。

作者注:熟悉 WebPKI 的读者会注意到交叉证书的工作方式完全相同。

此修复的伟大之处在于它不需要您重新签署现有的附加组件。 一旦浏览器收到新证书,所有附加组件将再次运行。 剩下的挑战是向用户提供新证书(自动和远程),以及让 Firefox 重新检查禁用的附加组件。

诺曼底和研究系统

讽刺的是,这个问题是通过一个名为“系统”的特殊附加组件解决的。 为了进行研究,我们开发了一个名为 Normandy 的系统,为用户提供研究成果。 这些研究在浏览器中自动执行,并增强了对 Firefox 内部 API 的访问。 研究可以将新证书添加到证书存储中。

作者注:我们不会添加具有任何特殊权限的证书; 它由根证书签名,因此 Firefox 信任它。 我们只需将其添加到浏览器可以使用的证书池中即可。

因此,解决方案是创建一项研究:

  • 安装我们为用户创建的新证书
  • 强制浏览器重新检查禁用的加载项,以便它们再次工作

“但是等等,”你说,“附加组件不起作用,我如何启动系统附加组件?” 让我们用新证书来签名吧!

把所有这些放在一起......为什么花了这么长时间?

因此,计划是:颁发一个新证书来替换旧证书,创建一个系统附加组件并通过 Normandy 将其安装给用户。 正如我所说,问题于 4 月 4 日 00:12 开始,并在当天 44:9 不到 6 小时后,我们向诺曼底发送了修复程序。 又花了 12 到 XNUMX 个小时才到达所有用户。 一点也不坏,但 Twitter 上的人们在问我们为什么不能更快地采取行动。

首先,颁发新的中级证书需要时间。 正如我上面提到的,根证书的密钥离线存储在硬件安全模块中。 从安全角度来看,这很好,因为根很少使用,应该受到可靠保护,但当您需要紧急签署新证书时,这有点不方便。 我们的一位工程师必须前往 HSM 存储设施。 然后,又多次尝试颁发正确的证书,但均未成功,每次尝试都需要花费一两个小时进行测试。

其次,系统附加组件的开发也花费了一些时间。 从概念上讲,它非常简单,但即使是简单的程序也需要小心。 我们想确保我们不会让情况变得更糟。 研究在发送给用户之前需要进行测试。 此外,必须对附加组件进行签名,但我们的附加组件签名系统被禁用,因此我们必须找到解决方法。

最后,当我们准备好提交研究后,部署就需要时间了。 浏览器每 6 小时检查一次 Normandy 更新。 并非所有计算机都始终处于开启状态并连接到互联网,因此修复程序需要一段时间才能传播给用户。

最后步骤

该研究应该可以解决大多数用户的问题,但并非所有人都可以使用。 一些用户需要特殊的方法:

  • 禁用研究或遥测的用户
  • Android 版本(Fennec)的用户,根本不支持研究
  • 在无法启用遥测的企业中使用 Firefox ESR 自定义版本的用户
  • 坐在 MitM 代理后面的用户,因为我们的附加安装系统使用密钥固定,这不适用于此类代理
  • 使用不支持研究的旧版 Firefox 的用户

我们对后一类用户无能为力——他们仍然应该更新到新版本的 Firefox,因为过时的版本存在严重的未修补的漏洞。 我们知道有些人仍然使用旧版本的 Firefox,因为他们想运行旧的附加组件,但许多旧的附加组件已经被移植到新版本的浏览器上。 对于其他用户,我们开发了一个补丁来安装新证书。 它作为错误修复版本发布(译者注:Firefox 66.0.5),因此人们会通过常规更新渠道获得它 - 很可能已经获得它。 如果您使用的是 Firefox ESR 的自定义版本,请联系您的维护人员。

我们知道这并不理想。 在某些情况下,用户会丢失附加数据(例如,附加数据 多帐户容器).

这种副作用是无法避免的,但我们相信在短期内我们已经为大多数用户选择了最佳解决方案。 从长远来看,我们将寻找其他更先进的架构方法。

经验教训

首先,我们的团队在发现问题后不到 12 小时内就创建并发布了修复程序,做得非常出色。 作为参加会议的人,我可以说,在这种困难的情况下,人们非常努力,几乎没有浪费时间。

显然,这一切根本不应该发生。 显然,调整我们的流程以减少此类事件发生的可能性并使补救变得更容易是值得的。

下周我们将发布正式的事后分析和我们打算进行的更改列表。 现在,我将分享我的想法。 首先,必须有更好的方法来监控潜在定时炸弹的状态。 我们需要确保我们不会发现自己处于其中一个突然起作用的情况。 我们仍在制定细节,但至少有必要考虑到所有这些事情。

其次,我们需要一种机制来快速向用户提供更新,即使在其他一切都失败的情况下(尤其是当)。 我们能够使用“研究”系统真是太好了,但它是一个不完美的工具,并且有一些不需要的副作用。 特别是,我们知道许多用户打开了自动更新,但不愿意参与研究(我承认,我也关闭了它们!)。 同时,我们需要一种向用户发送更新的方法,但无论内部技术实现如何,用户都应该能够订阅更新(包括修补程序),但选择退出其他所有内容。 此外,更新通道的响应速度应该比当前更快。 即使在 6 月 XNUMX 日,仍然有用户没有利用修复程序或新版本。 这个问题已经得到解决,但发生的事情表明了它的重要性。

最后,我们将仔细研究该附加组件的安全架构,以确保它提供适当的安全级别,并将破坏任何内容的风险降至最低。

下周我们将查看对所发生事件进行更彻底分析的结果,但与此同时我很乐意通过电子邮件回答问题: [电子邮件保护]

来源: linux.org.ru

添加评论