很多团队做多账号环境时,会把注意力放在 Cookie、代理和指纹上,却忽略浏览器扩展。扩展一旦拥有广泛的主机权限,就可能成为不同账号之间的共享通道:同一个扩展装在同一个浏览器 profile 里,所有标签页都能被它读取或注入。
一个典型的 Chromium 扩展包含三部分:后台脚本(Manifest V3 中是 service worker)、内容脚本(content script)和页面注入脚本。后台脚本负责事件处理、网络请求和扩展状态;内容脚本由浏览器注入到匹配的页面里,运行在独立的 JavaScript 世界(isolated world)中;页面注入脚本则运行在页面的主世界(main world),可以直接访问页面的 JS 对象。
内容脚本能读写 DOM,但默认不能直接访问页面里的 JS 变量;它通过 window.postMessage 或 chrome.runtime.sendMessage 与后台通信。这个隔离设计是为了安全,但它不等于“扩展看不到页面数据”:DOM 里的账号信息、表单内容、页面标题,内容脚本都能读到。
扩展的能力由 permissions 和 host_permissions 决定。常见的敏感权限包括:
cookies:读取和修改指定域名的 Cookie;tabs:访问标签页的 URL、标题和 favicon;webRequest / declarativeNetRequest:观察或修改网络请求;storage:保存扩展自己的数据;<all_urls> 或宽泛的 host 匹配:在所有站点注入内容脚本。一个只申请 activeTab 的扩展,权限范围有限;一个申请 <all_urls> 加 cookies 的扩展,基本可以看到用户在多个站点上的登录态和页面内容。多账号环境里,如果同一个扩展装在同一个 profile,它天然可以把 A 账号页面的数据带到 B 账号页面。
更隐蔽的是 web_accessible_resources 和 externally_connectable:前者允许页面加载扩展资源,后者允许指定站点直接给扩展发消息。权限配置不当,扩展就会变成页面与后台之间的双向通道。
一个最小权限的 Manifest V3 配置大致是这样:
{
"manifest_version": 3,
"name": "minimal-demo",
"version": "1.0.0",
"permissions": ["activeTab", "storage"]
}它只能在用户主动触发时访问当前标签页,不能在所有站点后台注入。
浏览器里有三层容易混淆的隔离:
这三层解决的是不同问题。进程隔离防的是跨站攻击,profile 隔离防的是数据混用,扩展隔离防的是页面脚本直接调用扩展 API。它们都不能自动保证“平台看到的是不同的人”。
扩展的存储也有边界:chrome.storage.local 按扩展和 profile 分开,但同一 profile 内的所有标签页共享同一份扩展存储。如果扩展把页面数据写进 storage,换账号不会自动清空。
第一,按 profile 管理扩展。不要把同一个扩展同时装在多个账号环境里;如果业务确实需要翻译或密码管理插件,为每个环境单独配置,并确认插件的数据不会跨环境同步。
第二,最小权限。检查扩展的 host_permissions 是否覆盖了不需要的站点;能用 activeTab 就不要用 <all_urls>;能不给 cookies 就不给。
第三,审计来源。只安装可信来源的扩展,定期检查 chrome://extensions 的权限变更。Manifest V3 下,扩展更新可能带来新的权限,浏览器会提示,但团队里未必有人注意。
第四,注意页面注入。需要访问页面主世界时,优先使用官方提供的 world: "MAIN" 机制,并限制注入范围;不要用宽泛的 eval 或远程脚本。
第五,检查扩展的更新策略。Manifest V3 的 service worker 可能在后台常驻,扩展更新后权限变化不一定立刻被团队发现;把扩展清单和权限纳入环境模板,切换环境时一起核对。
浏览器扩展是多账号环境里最容易被忽略的一层。它不像 Cookie 那样有明确的清理入口,也不像代理那样有明显的出口配置,但它的权限足够大时,可以跨页面读取数据、观察请求,甚至改变页面行为。
做环境隔离时,除了 Cookie、代理和指纹,也要把扩展列表、权限和注入范围纳入检查。多开窗口不等于隔离,扩展也不应该成为账号之间的共享通道。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。