LWN: 浏览器扩展开源项目中的恶意攻击!
共 5625字,需浏览 12分钟
·
2021-03-04 19:02
关注了就能看到更多这么棒的文章哦~
Malware in open-source web extensions
February 16, 2021
This article was contributed by Calum McConnell
DeepL assisted translation
https://lwn.net/Articles/846272/
2 月 4 日,世界上有数百万个浏览器标签页(browser tab)突然被终止掉了。并不是每个人都感到惊讶的,在过去四个月里,有十几个人都在等待这一悲剧的发生,看着 GitHub 上的评论开始快速涌入(https://github.com/greatsuspender/thegreatsuspender/issues/1263#issuecomment-773499950),他们松了一口气。名为 The Great Suspender 的这款 Chrome 扩展可以将不活跃的标签页暂停掉,它大约有 200 万用户,而这次就因为含有恶意软件而被强行卸载掉了。这对用户来说是一个严重问题,部分原因是因为难以将丢失的标签页再回复出来,但任何关注这个扩展的人在此前都看到了这款扩展中的满满恶意。
Who owns the code
这个扩展被攻陷,并不是因为某个狡猾的骇客溜进了 build infrastructure(请参考 https://www.linuxfoundation.org/en/blog/preventing-supply-chain-attacks-like-solarwinds/ ),也不是因为某些 meta 字符被错误地转义了(参看 https://lwn.net/Articles/844789/)。而是因为自由软件和开源软件社区的一个众所周知的问题:谁拥有代码?开放源码许可证的最主要意义就是能使这部分代码不再是局限于一个团体的控制之下。相反,代码是由围绕着它建立的社区所共同拥有的,而不是某个个人。然而,具体到许多类型的软件中去的时候,这个说法只是理论上正确。
在实践中这个理论不再奏效的原因是,代码并不会简单地从社区的一个成员转移到另一个成员身上。总是需要有一个规范的地方,来发布所有的 patch 以及 pull request。而这样的地方就需要一个负责人:一个操作服务器的人,他持有 GitHub 账户,对发布版本进行签名,并将它们推送给其他发行商。
但是,当原创作者决定不再参与时,会发生什么?Python 就是一个例子,我们可以看到这种情况确实会发生。然而,许多项目并未拥有专门的基金会和完整的治理体系,相反,它们可能只有一个维护者,负责管理来自社区的时不时的 patch。为开源项目托管代码的网站(如 GitHub)确实支持设置区分一个核心的维护者团队以及其他贡献者,每个人都能够继续自行开发项目。但有一些发布系统,比如 Chrome Web Store 或 Apple App Store,实际上就需要一个人对代码及其每一个版本进行负责。
由于原创作者只有自己一个人拥有这些分发渠道的账户(用户通常都是经过这些分发渠道来获取这个程序的),因此从逻辑上讲,他们有责任将控制权转移给未来的维护者,尽管未来的维护者们可能只对软件中的部分代码拥有 copyright。此外,由于分发渠道的账户是项目所有者的个人财产,他们可以出售该账户和相关的维护权。毕竟,虽然 Chrome 扩展的具体代码可能属于更大的社区,但分发账号肯定不是属于所有人的。
The Great Suspender 就发生了这样的情况,它是 Web Store 上的一个 Chrome 扩展,它的功能是暂停那些不活跃的浏览器 tab,停止这些网页上的运行脚本,并释放相关的大部分内存资源。2020 年 6 月,创建者、长期维护者 Dean Oemcke 决定不再参与该项目。他转让了 GitHub 仓库和 Web Store 的操作权限,并在 GitHub 上的一个 issue 中宣布了这一改动,但没有提到新维护者的身份。公告中甚至还提到了 purchase 这个引人关注的词,这就引发了大家的疑问,谁会花钱买一个免费的扩展?为什么?
当然,由于绝大多数用户对 The Great Suspender 的开源性质并不关心,所以很少有人注意到这一点,直到 10 月份,新的维护者在 Chrome Web Store 上发布了一个非常不起眼的版本。除了发布的版本与 Git 仓库的内容不一致、没有在 GitHub 上打上 tag、以及缺乏 changelog 这些小细节之外,看起来很平常。
如果不是因为我太无聊的话,我根本不会去搜索它的 changelog,也不会找到相关的 GitHub 仓库,更不会看到这个关于新的维护者在版本中加入恶意脚本的指控。更糟糕的是,如果这个版本不告诉我,我都不知道我升级了新版本:几乎所有的浏览器扩展在更新时都不会给出通知。因为 The Great Suspender 需要获取一个标签页进程的控制权来对它进行 suspend 操作,所以它有一个相当复杂的机制来警告拥有那些更新内容,以及实际进行更新,这直接导致了问题的发生。
Investigating
从 10 月份的发现开始,接下来的事情就像坐过山车一样:只有少数安全领域的新手决定要看看这个更新,并且我们却不知道该怎么做才能看到。现在,该扩展似乎正在从一个不相关的第三方域名下载并执行一个 JavaScript 文件。该域名看起来是 Open Web Analytics, 这是一个完全合法的替代 Google Analytics 的方案,并且早已用在这个扩展里了。好吧,看起来这里没有什么危险了。直到后来,我们发现该域名与此完全无关,实际上是提供了一个会链接到其他恶意浏览器扩展的脚本。虽然 Chrome 扩展的 JavaScript 被要求以未加混淆的形式(unobfuscated form)分发,但这类远程下载的脚本(显然)没有经过这个验证。由于这种混淆过的 JavaScript 文件很难通过阅读代码来理解其功能,而且实际用到的脚本可能也会有变化,因此该扩展程序具体做了什么事情,我们仍然不清楚。
虽然有些人怀疑这个远程下载的脚本是通过重写 referral header 来来进行广告欺诈,但这些怀疑的根据是来自其他那些使用了与这个脚本相同的 analytics ID 的恶意扩展的分析。在这次更新前不久,新的主任为了证明他增加拦截权限的请求的合理性,做了一些小改动。因此,人们担心远程脚本正在从 HTTP form 中采集登录信息,以及验证 cookies。不幸的是,很难确认这些怀疑:服务器提供了一个无辜的 Open Web Analytics 版本,将这些访问此页面的请求重新转发出去了,并且很可能进行了多层次的验证来确保真实版本难以被采集。由于谷歌已经将该扩展作为恶意软件删除,因此恶意版本的 JavaScript 代码很可能已经完全停止服务。调查人员在证明该扩展没有运行 Open Web Analytics 后,尽管该扩展明显努力伪装成 Open Web Analytics,但还是足够得出简单的结论,就是判定它是恶意软件,然后就进行了处理。
该版本已经导致超过 100 万个浏览器发出的所有 HTTP(s) request 都被转发到了恶意域名,这个版本是 2020 年 10 月发布的。在一个月后发布后续版本中已经删除了恶意代码,但似乎上一个恶意版本已经禁用了自动更新,因为大多数现在装上此扩展的浏览器都保持了那个恶意版本,直到它被强制删除。在被强制删除之前有四个月的时间,在这期间,该扩展的整个用户群不仅仅是容易被攻击,而且实际上是已经被攻击了。
这说明了另一个问题:人们如何慢慢忽视了扩展中的那些恶意软件的?每个发现恶意行为的用户的经历进展都差不多是这个样子:在短暂的愤怒之后,可能配合向谷歌报告,用户自己会卸载 Web Store 版本,并根据源代码来 sideload 一个安全的版本(这是防止 Chrome 自动更新到受影响版本的唯一方法)。结果,他们会脱离这个讨论,相关话题不再有热度,于是所有相关方都认为,由于大家现在已经免受恶意软件的影响,这不再是会影响到自己的问题了。与此同时,新的 GitHub issue 不断被人创建,将“紧急!正在发生安全问题” 的可怕警告推广开来,导致那些原本感兴趣的调查人员也不再关注了。相关讨论大多数时候并不活跃:在沉默了一个月之后,有几个 Twitter 账户在 1 月初提出了这个问题,引出了一些关于恶意软件的报告,但在谷歌最终禁止之前,大多数时间都是没有什么声音的。
other examples
Great Suspender 以前就曾经被入侵过,其他许多扩展也是如此。哪怕攻击者不去实际入侵大家的账户,而这个检查数百万用户的完整浏览活动的能力本身就是价值连城的。这使得这些 web 扩展成为了集团化攻击者的绝佳目标。一个极其相似的案例是两个扩展 Nano Adblocker 和 Nano Defender,它们都是从 uBlock Origin 分叉出来的。
UBlock Origin 是一个使用很广泛的、开源的、广告拦截扩展,目标是做到快速、轻量级和合理程度上的用户友好界面,并同时仍提供高级过滤功能。UBlock Origin 本身就是从最初的 uBlock 中 fork 出来的,它的原始创建者 Raymond Hill,在(你猜对了!)他将 uBlock 的所有权转让给了一个新的、不值得信任的维护者 Chris Aljoudi 之后,自己 fork 的。Aljoudi 不仅创建了一个只为了募集捐款的网站,此外还开始减少拦截功能,可以通过 "acceptable ads" 程序来允许某些广告。这实际上意味着,大型广告提供商只要简单付费就能让他们的广告不被屏蔽:简而言之,最初的 uBlock 又加入了一长串广告屏蔽的名单,而这些名单的作用跟大家想要的功能正好相反。
因此,Hill 创建了自己的 fork,现在叫 uBlock Origin,其中去除了这些改动。当 Hugo Xu 后来创建了 Nano Adblocker 时,这部分代码是基于 uBlock Origin 的,额外增加了功能允许用户来提交那些不被屏蔽的广告,以便日后审查和修复。徐还创建了一个扩展,以防止网站阻止用户使用基于 uBlock 的这类广告拦截器,这个扩展就是 Nano Defender。然而,由于世界上的网站变化巨大,需要不断进行评判分析,这个巨大的工作量导致 Xu 将这两个扩展程序卖给了一个未公开的土耳其开发者团体。Nano Defender 和它的 20 多万用户在最近被收购后,立即就被发现他们的个人数据被未经许可地收集了。
这两个例子都只是更多存在问题的浏览器扩展程序(甚至包括那些开源的扩展程序)中的两个例子而已。这些扩展是免费提供的,只需经过最低程度的审查,并且很容易在与合法扩展相同的渠道发布。因此,具有明确恶意行为的浏览器扩展程序一直在出现,也是现代恶意软件最流行的传播方法之一。
要让一个没有经验的用户相信这个扩展程序可以改善他们的搜索体验,或者说可以阻止恶意域名,往往是非常简单的。然后,开发者就在扩展中埋入一些代码,将用户的电脑变成一个看广告、给开发者们赚钱的机器。此外,由于用户安装后只与用户进行极少的交互,因此获取 login 信息后,即使是一个已有信任基础的开源扩展,也可能会变成安全隐患。当扩展程序可以简单地从看似无辜的 Analytics 提供商那里加载代码,Chrome Web Store 要求扩展程序中的 JavaScript 不允许经过混淆的这个措施事实上帮助并不大,甚至导致少数 JavaScript 开发人员自己安装和检查扩展程序来发现恶意软件时都无法有效进行。
虽然 Nano Defender 和 The Great Suspender 都已经从 Web Store 中删除,用户也改变了工作习惯或切换到其他扩展程序(分别是 uBlock Origin 和 The Marvellous Suspender),但这里的根本问题依然存在。Chrome 扩展的平台方长期以来人手不足,动作缓慢。这一点从谷歌要花了 4 个月的时间才能删除 The Great Suspender 就能看出来,这已经是新闻媒体报道这些问题后整整一个月之后了。为了防止这些问题在未来再次发生,谷歌一直在推行 "Manifest V3",提出了许多有争议的要求,但是其中就包括禁止执行任何从远程服务器加载的 JavaScript 。虽然这不会阻止 Nano Defender 攻击,但它将使得检查 The Great Suspender 所采用的攻击脚本的工作更加直接,这将使识别和删除恶意软件变得更加容易。这个问题引发的其他问题是扩展的作者无法与用户交流了,以及为所有用户都自动更新扩展带来的风险。虽然自动更新是一个有用的功能,但正如这些事件所表明的,自动更新也存在一些让人担忧的地方。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~