隐藏在众目睽睽之下:浏览器扩展程序带来的风险(上)

如果您曾用浏览器扩展程序(Browser extension)定制了您的浏览体验,请举个手。也许您曾给您的浏览器添加了一个广告拦截器,或一个用于检查拼写,甚至一个反指纹追踪的浏览器扩展。然而,如果这些扩展程序并非像您想象的那样安全,而在实际上对您的在线活动带来了真正的风险,那该怎么办?

我们的研究恰恰揭示了这些影响深远的浏览器扩展的危险。我们通过网民们最常使用的平台来进行扩展程序探测,并撰写了研究报告。报告由两部分组成,在这一系列报告中,我们将深入探讨浏览器扩展程序的风险及其探测方法,然后,进一步讨论它们的普遍性、对隐私的影响以及我们应当采取的措施。

基础知识:浏览器扩展 vs 插件

浏览器是我们互联网生活的重要组成部分。我们每天都要成百上千次地用浏览器来阅读新闻、访问账号、发送电子邮件、展开各种业务。然而,浏览器厂商并不能满足每个人的特殊需求。乐高的格言(Det bedste er ikke for godt——只有做到最好才足够)并不能为浏览器厂商所用。通过提供浏览器扩展或附加组件,浏览器厂商将定制工作留给了开发者社区。就像乐高一样,只需将HTMLCSSJavaScript等碎片拼接在一起,就可以定制出满足不同需求的浏览器。

说到这里,很多人容易混淆这两个类似的名词:插件(plugin)和扩展程序(extension)。

插件是可执行的二进制文件,而扩展程序则是使用浏览器API的脚本代码。一些插件如Adobe Flash,几乎被所有的浏览器厂商弃用,但扩展程序仍然每天被人们广泛使用。

扩展程序每天都被广泛使用。然而,就像任何事物一样,它们并非没有缺点。让我们一起来抽丝剥茧。

我们不可能用同一种方式笼统地分析它们——人们最常使用的浏览器扩展商店Chrome网上应用店提供了84个类别的扩展程序,涵盖了从效率管理到天气预报、加密货币、约会、时尚等方方面面。

可惜的是,数字世界就像现实世界一样,每一种舒适感背后,都有其缺点。所以说,我们思考安装扩展程序是否会损害我们的隐私,这种疑虑并非空穴来风。您稍后也会发现,研究给出的答案,也是很有说服力的。

浏览器扩展程序固有的风险

当您选择接受扩展程序向您索要权限的要求时,您赋予了它们强大的权力——它们可以读取浏览器历史和cookie,或拦截请求与相应。虽然这些风险因素并不在本篇文章的讨论范围内,但我们认为有必要提醒您,不仅在安装前,而且在更新扩展程序后,它都可能会向您索要一些额外的权限。此外,当浏览器扩展程序被卖给另一位开发者或公司时,另一种威胁也将产生。在这种情况下,买方可能会利用浏览器扩展来恶意搜集数据。

好了,接下来,我们还是回归正题,来谈谈浏览器指纹的相关问题。

扩展程序作为浏览器指纹的一部分

Picture from the search Extension Breakdown: Security Analysis of Browsers Extension Resources Control Policies - 2017
图片来自《细数扩展程序:浏览器扩展资源控制政策的安全性分析》2017年。

浏览器扩展程序可以被探测吗?与插件相比,浏览器并没有提供类似“navigator.plugins”这样的方法来一次性获取用户已安装的扩展程序列表。然而,人们知道扩展程序可被探测,已有一段时间了。早在2007年,就有相关研究的实证性报告和博文;2014年后,人们进一步加深了对这一话题的研究。举个例子,起初的研究像是充满好奇心的骇客提出了一个问题,我们可以从XSS漏洞利用框架BeeF的一部分中,看到相关浏览器指纹的代码。

现在,我们就这一话题掌握的信息越来越多,研究发展也越来越快。下面,我们就来悉数浏览器扩展探测的四个关键领域。

1. Web Accessible Resources (WAR)

扩展程序是包含许多数字资源的档案文件,如JavaScriptHMTLCSS和图像文件。Web Accessible Resources是一种通过网站访问存储在您电脑上的扩展程序的文件,从而了解您是否安装了某扩展程序的方法。

A folder view of NoScript browser extension.
NoScript浏览器扩展程序的文件夹视图。

从早期的扩展程序探测开始,研究的重点就是利用这些方式来探测扩展的存在。在Chrome浏览器中拥有一个独特的32字符扩展标识符无疑有助于实现这一目的。例如,当一个扩展的标识符和信息被识别时,像下面这样的基本代码就可以帮助网站了解该扩展程序是否已被安装、在浏览器上是否具有活性。

<img src=”chrome-extension://AN_IMAGINERY_EXT_ID/IMAGINERY_RESOURCE.png” onload=”alert('Extension exists');” oneror=”alert('Extension does not exist');”/> 

虽然这种探测机制对所有的扩展程序文件都有效,但谷歌浏览器在2013年以第2manifest.json的形式推出了反扩展程序探测的预防机制。

根据这次更新,只有manifest.jsonweb_accessible_resources(WAR)节点定义的文件才能被扩展程序加载出来——也就是说,被网站加载。

Web Accessible Resources

这种方法被用于学术研究和非学术性的扩展程序探测至2019年。

2. 篡改DOM

到目前为止,我们这个行业的人基本上都在关注探测扩展程序的方法。2019年,我们发现,许多扩展程序通过篡改DOM现身。从本质上说,这意味着,某些无法被直接观察到的对页面源代码的改动,在进一步检查时将被发现;最终,扩展程序能被探测到。

这就让人产生了这样的想法:Firefox用于防止探测扩展程序的扩展程序ID随机化机制,实际上却带来了另一个更要紧的风险:随机化的ID有可能被恶意网站用来追踪一个独特的用户。

Firefox的扩展程序ID随机化机制本身存在着严重的风险:创建一个随机化的ID,恶意网站就可以利用这个ID来追踪用户。

那么,DOM篡改是如何进行的呢?浏览器扩展会以多种方式影响网站页面的DOM。通过观察这些DOM的变化,我们就可以检测出浏览器扩展。例如,被广泛使用的浏览器扩展程序Grammarly,下载量超过一千万,它通过在文档主体中添加一个属性data-gr-ext-installed来达到这种效果。因此,通过使用下面这样的代码,我们就可以探测到这个扩展程序。

if(document.body.hasAttribute("data-gr-ext-installed")) alert("Grammarly Detected");

即使是一些专门用来保护用户的扩展程序,其实也会产生同样的风险。这里需要强调的是,不少人喜欢用浏览器扩展程序来保护自己不被浏览器指纹攻击。但是,这类扩展程序会直接影响到DOM和其他浏览器对象。由于其留下的痕迹,大多时候,相较于其他扩展程序,探测它们更容易。我们以据称可以防御WebGL指纹的WebGL指纹卫士 WebGL Fingerprint Defenderolnbjpaejebpnokblkepbphhembdicik)为例,来揭示DOM篡改。

if(document.documentElement.dataset.hasOwnProperty("wgscriptallow")) alert("WebGL Fingerprint Defender");

另一个例子是“Don’t Fingerprint Me”扩展程序(nhbedikkbkakbjipijipejfojanppbfg),它对窗口(window)对象有直接的影响。它给窗口对象增加了一个属性dfpm,整体长为3689个字符。

“Don’t Fingerprint Me”这样的扩展程序,号称能保护您,其实很容易被检测到。

那么Firefox的情况如何?想象一下,您在网页中加载一个扩展程序资源,使用的扩展程序URL中包含一个随机的扩展ID:一个恶意网站可以获得这个随机ID,并追踪用户。Firefox开发者声称,随机ID是在每个浏览器进程中被创建的。然而,研究表明,即使删除浏览器历史记录或更新浏览器,这些随机ID也会保持不变。请看下方的表格,它显示了随机ID在哪些情况下会发生改变。

When do randomized IDs change?
随机ID何时改变?

这意味着,如果您管理着多个账户,并且相信Firefox可以保护您的身份,那么您的安全便岌岌可危了。最近的研究证明了这一点:在结合泄露和探查攻击的情况下,尽管ID随机化,但多达90%的扩展程序内容是可识别的。

然而,需要注意的是,每当您启动Multilogin软件中的Stealthfox浏览器配置文件,随机ID都会重新生成。换句话说,如果您使用Multilogin,这类攻击将不再会发生。

需要注意的是,每当您启动Multilogin软件中的Stealthfox浏览器配置文件,随机ID都会重新生成。换句话说,如果您使用Multilogin,这类攻击将不再会发生。

3. 行为分析

有些扩展程序不使用WAR文件,对DOM没有任何副作用。但是,只要观察它们引起的一些行为现象,我们还是可以发现它们的。例如,扩展程序uBlock Origin是用来屏蔽广告的,虽然该扩展程序将一些页面列为白名单,作为WAR使用,但它也试图阻止内部访问它们。通常情况下,如果您试图访问manifest.json中没有被列入白名单的文档,这部分资源将被发送到chrome://invalid URL。然而,在uBlock Origin中,由于扩展程序本身试图干预,URL不会被路由到chrome://invalid,它将保持原样。我们就可以通过这种行为来识别扩展程序。


<link rel="prefetch" href="chrome-extension://cjpalhdlnbpafiamejdnhcphjbkeiagm/web_accessible_resources/1x1.gif"/> 
<script> 
if(performance.getEntriesByName("chrome-extension://cjpalhdlnbpafiamejdnhcphjbkeiagm/web_accessible_resources/1x1.gif").length>0) { detectedPlugins.push("UBlock Origin"); 
} 
</script>

4. 内部消息传送或外部资源加载

浏览器扩展由内容脚本、后台脚本、manifest.json文件及其资源等几个部分组成。内容脚本是加载网页的一部分;后台脚本,顾名思义,是在后台运行的。由于浏览器厂商设计的安全模型,这几个部分是彼此隔离的,不能直接互相联系。它们必须使用扩展程序API或窗口消息等内部消息传递机制来进行沟通。

一个扩展程序也可以通过在它的manifest.json文件中使用externally_connectable指令,将一些URL列入白名单,这个被列入白名单的网页就可以使用runtime.sendMessage API来发送消息。但是,这个externally_connectable指令不允许使用通配符,并且至少需要一个二级域。尽管如此,扩展程序可以也需要以某种方式与网页进行通信。一些扩展程序,如MeetMe Dolby Voice 1.1(lflnplggpolkcgknahacafilopgngelc),使用window postMessage的方法在内容脚本和网页之间发送并接收消息。

Content script of MeetMe Dolby Voice 1.1. Extension
扩展程序MeetMe Dolby Voice 1.1的内容脚本

任意一个网站都可以监听到这个消息,并通过这个方法对扩展程序进行指纹识别。此外,一些扩展程序也会加载额外的信息以及扩展本身的web可访问信息。我们可以通过使用Performance API来探察这些信息,如performance.getEntries(“resource”)

在本系列的第一部分中,我们研究得出这样的结论:探测浏览器扩展程序及其容易,包括那些所谓旨在保护您的浏览器的扩展。如果您依赖浏览器扩展程序建立了多个网站账号并展开相关业务,那么,我们必须提醒您重视浏览器扩展程序带来的风险。

请您继续阅读研究报告的第二部分。在这部分中,我们将讨论扩展程序探测在实际场景中的普遍性,包括在LinkedInYouTube等流行平台;此外,我们也将进一步讨论,我们应该使用哪些缓和策略。请您关注我们的博客,并确保订阅我们的电子邮件,您就不会再错过任何最前沿消息更新。