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

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

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

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

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

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

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

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

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

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

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

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

"这是啥?"

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

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

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

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

打包领取卡颂原创React教程、加入人类高质量前端群

浏览器插件能做什么?

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

  • GPT插件能帮我们一键总结网页内容

  • 翻译插件能实时翻译网页内容

  • 去广告插件能去掉网页牛皮癣,还我们清爽的页面

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

  • 获取我们的实时位置

  • 读取、修改我们复制粘贴的内容

  • 读取cookie、浏览历史

  • 屏幕截图

  • 记录键盘输入

  • 等等

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

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

事实真的这么简单么?

安全约束够么?

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

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

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

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

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

Service Worker

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

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

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

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

用户敏感数据

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

js 复制代码
[...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就是最好的下手目标。

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

js 复制代码
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后,用户也不会有任何察觉。

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

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

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

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

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

js 复制代码
// 修改标题
document.title = searchParams.get('title);

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

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

js 复制代码
await chrome.tabs.update(idleTab.id, {
  url,
  active: false,
});

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

js 复制代码
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,退出所有的账号登录并修改密码。

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

相关推荐
zhanghaisong_201518 分钟前
Caused by: org.attoparser.ParseException:
前端·javascript·html·thymeleaf
Eric_见嘉21 分钟前
真的能无限试(白)用(嫖)cursor 吗?
前端·visual studio code
DK七七1 小时前
多端校园圈子论坛小程序,多个学校同时代理,校园小程序分展示后台管理源码
开发语言·前端·微信小程序·小程序·php
老赵的博客1 小时前
QSS 设置bug
前端·bug·音视频
Chikaoya1 小时前
项目中用户数据获取遇到bug
前端·typescript·vue·bug
南城夏季1 小时前
蓝领招聘二期笔记
前端·javascript·笔记
Huazie1 小时前
来花个几分钟,轻松掌握 Hexo Diversity 主题配置内容
前端·javascript·hexo
NoloveisGod1 小时前
Vue的基础使用
前端·javascript·vue.js
GISer_Jing2 小时前
前端系统设计面试题(二)Javascript\Vue
前端·javascript·vue.js
喔喔咿哈哈2 小时前
【手撕 Spring】 -- Bean 的创建以及获取
java·后端·spring·面试·开源·github