0

原来浏览器插件有这么多风险?

 6 months ago
source link: https://www.51cto.com/article/783358.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原来浏览器插件有这么多风险?

作者:卡颂 2024-03-11 10:15:29
有人会说 —— 我只使用那些信得过的插件。但今天信得过的插件,明天就一定信得过么?在暗网中,「用户量大的免费浏览器插件」能卖不错的价钱。
07ba39c86ef621eb491851bcd44b511ef9608a.png

嫦美找到我时,整个人是崩溃的 —— “卡颂,我好像被监视了”。

傍晚的星巴克,她的影子被吊灯拉得很长,颤抖着如同她此刻的内心。

“怎么回事?”我尽量让声音听起来平静些。

“最近认识个男生,是我MBA同学,对我很热情,也很懂我”嫦美环顾四周,仿佛随时会有什么东西从夜色中跳出来。

“缘分啊,这不很好嘛?”我笑着说。

“不是那种心有灵犀的懂,是那种「生活起居都被监视的懂」”嫦美解释道。不待我回应,又补充道:“这次约你出来,也是想让你帮忙看看我电脑有没有被植入啥监听木马”。

说罢,从背包里取出MacBook Air递给我。

“Mac一般安全性都蛮高的,你最近没装啥来路不明的应用吧?”一边摆弄她的电脑,我一边问道。

“我也不会装应用,平时主要就上上网、刷刷剧”。

浏览完她的应用列表,我顺手打开了浏览器,又习惯性打开插件列表。

这时,一个浏览器插件吸引了我的注意:

2153cca02f1d57ec884226794bbac23d92ac51.png

“这是啥?”

“奥,我们MBA的网课需要在这个平台看。这个平台很严,看课不能快进,也不能切换到其他页面。这是那个男同学发我的,装了后就能突破这些限制,还挺方便”说罢,嫦美皱了皱眉“和这个插件不会有关系吧?”

“不好说,等我看看插件源码”。

事实证明,这个插件真的有问题......

本文参考文章Let's build a Chrome extension that steals everything[1]

浏览器插件能做什么?

浏览器插件为我们上网提供了极大便利,比如:

  • GPT插件能帮我们一键总结网页内容
  • 翻译插件能实时翻译网页内容
  • 去广告插件能去掉网页牛皮癣,还我们清爽的页面

实际上,浏览器插件除了能「分析并修改原始页面」外,还能:

  • 获取我们的实时位置
  • 读取、修改我们复制粘贴的内容
  • 读取cookie、浏览历史
  • 记录键盘输入

可以说,有心人只要利用得当,就能通过浏览器插件获得我们上网的所有足迹。

这时,有人会说:“插件能做这些没错,但必须申请必要的权限,我不给他权限不就行了?”

事实真的这么简单么?

安全约束够么?

《Building Browser Extensions》一书作者「Matt Frisbie」为了演示浏览器插件的潜在安全问题,构造了一个「会申请全部49项权限」的chrome浏览器插件spy-extension[2]。

当你在浏览器安装这个插件后,浏览器确实会提示你「插件申请的权限」:

33af6cc43106c5392ce30077b9fe0c65211ce9.png

不过,等等!明明申请了49项权限,这里为什么只显示5项?原来,窗口显示的内容行数有限,超出部分需要拖动滚动条才会显示。

可是,又有几个用户会发现「在申请的5项权限下面,滚动条后面还隐藏了44项权限呢」?

一旦有了权限,想做什么就取决于插件作者的想象力了。可以被用来做坏事的WebExtensions API非常多,比如:

Service Worker

后台运行的Service Worker可以监听发出的网络请求,并在请求发送到网络之前修改它们。

这意味着插件可以使用Service Worker发送数据到服务器,或者在用户浏览网页时拦截请求并发送额外的数据。

由于Service Worker运行于一个独立的后台进程中,所以打开调试工具的Network面板看不到插件发出的请求:

84d369223ddc93014da873b6e1702972194f4b.png

都有哪些有价值的数据可以收集呢?

用户敏感数据

最简单的,监听用户键盘输入:

[...document.querySelectorAll("input,textarea,[contenteditable]")].map((input) =>
  input.addEventListener("input", _.debounce((e) => {
    // 处理 用户输入
  }, 1000))
);

除此之外:

  • chrome.cookies.getAll({})会以数组的形式返回浏览器的所有cookie
  • chrome.history.search({ text: "" })会以数组形式返回用户的整个浏览历史记录
  • chrome.tabs.captureVisibleTab()会静默将用户当前正在查看的页面截图,并以data URL的形式返回。
  • chrome.webRequest可以让插件监控所有Tab的流量

上述API结合Service Worker传输数据,用户在插件作者面前无异于裸奔。

更高阶的玩法

据嫦美表示 —— 她那个MBA同学好像知道她住哪儿,这是怎么做到的呢?很有可能是通过「获取地理位置」的插件功能。

一个网课插件获取地理位置,这不是太奇怪了么?可是嫦美一点都没发觉,这是怎么办到的?

如果插件脚本获取地理位置(通过navigator.permissions.query({ name: "geolocation" })),将询问用户授权。

但如果「被注入脚本的网站」已经获得用户的地理位置授权,插件不需要授权就能静默使用对应功能。

举个例子,如果百度地图向你请求「获取地理位置」的授权,这很合理,你也大概率会同意。

如果恶意插件可以向百度地图注入脚本,当你访问百度地图时,他就不用再获取授权就能访问你的地理位置。

借尸还魂之法

以上所说的所有功能都局限在 —— 插件向已有网站注入脚本。那插件是否能不被察觉的直接打开恶意网站呢?

答案是 —— 可以,我愿称其为「借尸还魂」之法。

很多朋友都会打开多个浏览器Tab,但常用的可能就是其中几个,剩下的Tab会闲置很长时间。

而这些「闲置的Tab」就是最好的下手目标。

e2ee5d1023a053b498a8075bd1d0961b048bb9.png

经常打开很多Tab

首先,插件通过以下代码筛选出闲置的Tab:

const tabs = await chrome.tabs.query({
  // 筛选用户当前没使用的Tab
  active: false,
  // 筛选用户没有pin的Tab,pin的Tab使用频率通常比较高
  pinned: false,
  // 不使用有音频的Tab
  audible: false,
  // 使用已经加载完毕的Tab
  status: "complete",
});

// 筛选出闲置Tab
const [idleTab] = tabs.filter(/** ...省略其他筛选条件 **/)

只要恶意网站的标题、图标(favicon)与闲置Tab一致,那么用恶意网站替换闲置Tab后,用户也不会有任何察觉。

举个例子,如果闲置Tab是React官网,那恶意网站只需要标题是React,图标是React,即使闲置Tab跳转到恶意网站,从Tab外观上也无法区分。

14097e2746f1734438a306be3a91a9d87dbb6c.png

下面的代码构造了恶意网站的url,其中「与闲置Tab一致的标题、图标」保存在url searchParams中:

// 将标题、图标保存在searchParams中
const searchParams = new URLSearchParams({
  returnUrl: idleTab.url,
  faviconUrl: idleTab.favIconUrl || "",
  title: idleTab.title || "",
});

const url = `${chrome.runtime.getURL(
  "恶意网站.html"
)}?${searchParams.toString()}`;

恶意网站在url searchParams中取出标题、图标数据,并替换:

// 修改标题
document.title = searchParams.get('title);

// 修改图标
document.querySelector(`link[rel="icon"]`)
  .setAttribute("href", searchParams.get('faviconUrl'));

最后,用恶意网站替换闲置Tab的网站:

await chrome.tabs.update(idleTab.id, {
  url,
  active: false,
});

恶意网站只需要在「做完坏事后」或「用户重新点击 闲置Tab 时」跳回原来的网站即可。代码如下:

const searchParams = new URL(window.location.href).searchParams;

function useReturnUrl() {
  // 跳回原来网站
  window.location.href = searchParams.get('returnUrl');
}

if (document.visibilityState === "visible") {
  useReturnUrl();
}

// 用户访问了闲置Tab
document.addEventListener("visibilitychange", () => useReturnUrl());

// ...开始做坏事

// 做完坏事,跳回原来网站
useReturnUrl();

从用户的视角看,当他点击闲置Tab时,网站重新加载。对于一个闲置的Tab来说,重新访问时加载页面是再正常不过的逻辑。

只是用户不会知道,这并不是「网站重新加载」,而是「退回到前一个网站」。

有人会说 —— 我只使用那些信得过的插件。

但今天信得过的插件,明天就一定信得过么?在暗网中,「用户量大的免费浏览器插件」能卖不错的价钱。

为什么会有人收购这类「没有商业价值的免费插件」呢?一种可能是 —— 收购后向代码中投毒,只要用户升级插件就会中招。

所以,好用的插件不一定没问题,今天没问题的插件明天也不一定没问题。

对于嫦美来说,技术上能做的只能是删除插件、清除缓存、清除cookie,退出所有的账号登录并修改密码。

但似乎更大的危险,来自现实世界......

[1]Let's build a Chrome extension that steals everything:https://mattfrisbie.substack.com/p/spy-chrome-extension。

[2]spy-extension:https://github.com/classvsoftware/spy-extension。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK