装个浏览器插件它能看见什么:权限清单怎么读
授权与合规声明
本文全部操作对象均为自建隔离靶场(本机容器或隔离虚拟机),涉及安全测试的环节必须以取得合法授权为前提。未经授权的渗透测试违反《中华人民共和国网络安全法》与《刑法》相关条款,须承担相应法律责任。本文只讲环境配置、版本对照与靶场隔离,不含任何攻击步骤、利用载荷与绕过手法,请勿将文中环境指向任何非自有系统。
一、装完才想起来问:它到底能看见什么
1.1 三个问题,其实是同一个问题
你装过一个插件。可能是护眼的、翻译的、比价的,也可能是某个网站提示你「安装助手体验更好」。装的时候屏幕上弹出一个框,列了几条,你扫了一眼,点了确认。整个过程不到十秒。
过一阵子,你在别处看到有人讨论某类插件会收集浏览记录。你回头看自己装的那几个,心里冒出三个问题:它能不能看到我访问过的所有网站?它能不能看到我在页面里填的东西?它能不能动我的登录状态?
这三个问题听着是三件事,往下追一层,是同一件事:这个插件在浏览器里被允许做什么。而这件事不由它自己说了算,也不由它的介绍页面说了算,由它安装包里的那份清单说了算。
浏览器给你弹的那个框,内容就是从这份清单里生成的。你看不懂那个框,通常不是因为框写得太绕,是因为没人告诉过你:清单里的字段,和「它能干什么」之间是怎么对上的。
1.2 介绍页是宣传,清单是边界
先分清两种文本。
一种是商店里的介绍:一句话功能、几张截图、一段「我们重视您的隐私」。这类文本没有任何约束力。它写「只读取当前页面」,代码里不做,也没有任何机制会拦住它。
另一种是安装包根目录下的清单文件。它由浏览器读取、由浏览器执行。清单里写了的,浏览器才会放行;清单里没写的,插件调用对应接口时会被直接拒绝。所以判断一个插件能看见什么,唯一可靠的入口是清单。
这也是为什么装的时候会弹框:浏览器把清单翻译成人话给你看,然后把决定权交给你。你点了确认,等于承认这份清单所描述的能力。
1.3 两个字段,先认脸
清单里和权限相关的字段有两个,名字很像,作用完全不同:
| 字段 | 官方说明(原文) | 它管的是 |
|---|---|---|
"permissions" | 「包含来自已知字符串列表的项。更改可能会触发警告。」 | 你能调用哪些浏览器接口 |
"host_permissions" | 「包含一个或多个用于授予对一个或多个主机访问权限的匹配模式。更改可能会触发警告。」 | 这些接口能在哪些网址上生效 |
⚠️代码待验证
permissions → 能调哪些接口 host_permissions → 这些接口在哪些网址上生效 两者取交集 → 它在这个网址上实际能做的事两个字段都提到「更改可能会触发警告」——这句话很重要,它说明权限不是装完就固定不变的:插件升级时如果新增了权限,浏览器会再提示你一次。所以「我装的时候它没要那么多」不构成安全依据,你要看的是它现在的清单。
本节的引文出自 Chrome for Developers 的《声明权限》中文页面,页面口径以截至 2026-10-24 抓取到的版本为准。
二、两类权限:钥匙串,和门
2.1 API 权限:钥匙串上给了哪几把
"permissions"里的每一项,基本对应一类浏览器接口。写"tabs",它就能调标签页相关的一批方法;写"cookies",它就能调 Cookie 相关的接口;写"webRequest",它就能挂网络请求的监听。
这里有个容易误解的地方:接口权限只管「能不能调这个方法」,不管「这个方法作用在哪个网站上」。一个只有"cookies"的插件,能调 Cookie 接口,但它在你的网银页面上读不到东西——因为它没有被允许碰那个网址。这就引出第二类权限。
2.2 主机权限:这把钥匙能开哪几扇门
"host_permissions"里放的是匹配模式,也就是网址的匹配规则。https://example.com/*是某站的整站,<all_urls>是所有支持的协议下的所有地址。它决定上一条里那些接口的作用范围。
官方文档对两者的关系写得很清楚:「主机权限允许扩展程序与网址的匹配模式进行互动。除了自身的 API 权限之外,某些 Chrome API 还需要主机权限」。
注意最后半句——某些 API 还需要主机权限。这句话的意思是:光有 API 权限不够,还要有对应网址的主机权限,那个接口在那些页面上才真正可用。反过来,光有主机权限没有 API 权限,你也没法调那个接口。两个条件是与的关系。
所以「这个插件能看见什么」这句话,准确的问法是:它申请了哪些 API 权限,以及这些权限被限定在哪些网址上。
2.3 一个常见的错判
很多人看清单只看"permissions"这一栏,看到里面没有"tabs",就断定「它读不了我的网址」。这个推断不成立,原因在第三章第三节会讲——有些动作不需要主机权限,有些能力可以由别的权限间接提供。也就是说,清单是一个需要整体读的结构,不是逐项对照的账本。
反过来也有一种错判:看到host_permissions里写着<all_urls>,就认为「它把我的所有数据都拿走了」。也不对。主机权限给的是「接触的资格」,具体接触了什么、传没传出去,清单不告诉你,那属于代码行为。清单能回答的是能力上限,不是行为记录。这个区分贯穿全文,请先记住。
三、主机权限换来的六件事
3.1 官方列举的六类动作
官方文档在讲主机权限时,列举了需要它的六类动作。这份列举值得逐条看,因为它就是「主机权限能换来什么」的官方答案:
| 序 | 动作 | 对普通用户意味着什么 |
|---|---|---|
| 1 | Service Worker 里发fetch() | 它能代你向别的网站发起请求,并读到返回内容 |
| 2 | 用tabs读敏感标签页属性(网址、标题、favIconUrl) | 它知道你打开了哪些页面、页面叫什么 |
| 3 | 以编程方式注入内容脚本 | 它能在页面里运行自己的代码 |
| 4 | 用webRequest监控和控制网络请求 | 它能看到这个页面往外发了什么 |
| 5 | 用cookies访问 Cookie | 它可能碰到你的会话凭证 |
| 6 | 用declarativeNetRequest重定向和修改请求 | 它能改变请求的去向和内容 |
六条里,第 1、6 两条离日常感受远一点,先放着。剩下四条是初学者最容易有体感的,逐个说。
3.2 读网址和标题:为什么「只是一个网址」也敏感
一个网址里能装的信息比你想的多。搜索词在查询串里,后台的页面路径在路径段里,有些站点把一次性凭证直接放在地址上。标题同理:邮件标题、订单标题、文档标题,都可能出现在标签页标题里。
所以「它只读网址,不读页面内容」这句话,安慰作用有限。把一周的网址和标题按时间排出来,足以画出你的作息、你在哪些系统里干活、你最近在查什么。这也是为什么这一类权限单独被点名为「敏感标签页属性」。
3.3 注入脚本:真正意义上的「看得见页面」
「以编程方式注入内容脚本」是六条里最需要留意的一条,因为它跨过了界线:前面几条看到的是关于页面的信息,这一条看到的是页面本身。脚本注入进去之后,页面里的 DOM 对它就是可读的——包括你填在输入框里的内容、渲染出来的列表、以及页面上任何一处文字。
注意这里说的是能力,不是行为。绝大多数正常插件用它来做页面增强:高亮、批注、取词翻译。同一把钥匙能开的门,用途可以很正,也可以不正,清单不区分这两种用途。你要判断的是:这个功能值不值得给它这个能力。
3.4 看网络请求,和读 Cookie
看请求这一条(webRequest)的意义在于:页面里发生的事,很多不体现在 DOM 上,而体现在它往外发了什么。挂上这个权限,请求的地址、时机、内容都在视野里。
读 Cookie 这一条(cookies)更直接。会话凭证通常存在 Cookie 里,拿到它就等于拿到「你处于登录状态」这个事实。这也是为什么在权限讨论里,cookies和host_permissions一起出现时,值得多看一眼它申请的范围——是全站,还是几个具体域名。
Cookie 本身的属性(作用域、有效期、标记位)是另一个话题,本文不展开。
3.5 三个「不需要主机权限」的例外
官方文档同时给了三个例外,这三点是理解清单的关键:
| 例外 | 说明 |
|---|---|
持"tabs"权限时用chrome.tabs访问标签页 | 有了 API 权限,一部分标签页操作不再额外要主机权限 |
用chrome.debugger | 调试类接口走的是另一套授权 |
| 清单里已声明的内容脚本 | 声明式注入在安装时就被一并授权了 |
这三条例外合起来说明一件事:能力的来源不止一处。所以读清单的正确姿势不是「这栏没有就安全」,而是「这几栏加起来,它到底拿到了什么」。这也是本文反复强调「整体读」的原因。
四、activeTab:把授权推迟到你点的那一下
4.1 什么叫「用户调用」
activeTab是清单里一个很特别的权限。官方的定义是:「"activeTab"权限可让扩展程序在用户调用扩展程序(例如点击其操作)时临时访问当前活跃的标签页。」
关键词有两个:调用和临时。先说调用。官方给了四种被认可的手势:
| 手势 | 具体动作 |
|---|---|
| 执行操作 | 点工具栏上那个图标 |
| 执行上下文菜单项 | 右键菜单里选它那一项 |
| 通过 Commands API 执行键盘快捷键 | 你按了它注册的快捷键 |
| 接受来自多功能框 API 的建议 | 你在地址栏里选了它给的候选 |
四种的共同点:都必须是你做的动作。插件不能自己「调用自己」,也不能靠定时器、靠页面加载事件来获得这份授权。这一条是整个机制的支点——授权的发起者从「安装时的你」变成了「此刻的你」。
4.2 临时到底多临时
拿到 activeTab 之后,它能做三件事:同时声明"scripting"时可以调scripting.insertCSS()或scripting.executeScript();通过返回tabs.Tab对象的接口拿到当前标签页的网址、标题和 favicon;用webRequest拦截这个标签页发往主框架来源的请求。
失效的规则写得很具体:「对标签页的访问权限在用户位于相应网页上时有效,并在用户离开或关闭标签页时被撤消。」也就是说,你切到别的标签页、或者把这个标签页关掉,授权立刻结束。文档还给了一个更细的例子:在example.com上点的,跳到example.com/foo仍然保留,换到另一个域就撤销。
这条规则的实用含义是:同一个网站上你点几次,它就获得几次授权;你不点,它一次都没有。这不是一个「装了就有」的权限。
4.3 分水岭:为什么它不弹警告
这是全文最该记住的一句官方表述:「此方法可替代"<all_urls>"的许多用途,但在安装期间不显示警告消息」。
配套的另一半是:如果不使用 activeTab,想达到类似效果,就得申请「对每个网站的完全持久访问权限」。
于是安装时的那个框,成了两种授权模式的分水岭:
| 对比项 | <all_urls>这类主机权限 | activeTab |
|---|---|---|
| 授权时机 | 安装时一次性给 | 每次你点它时给 |
| 有效范围 | 所有匹配的网址 | 当前这一个标签页 |
| 有效时长 | 持久,直到你撤销或卸载 | 直到你离开或关闭该页 |
| 安装时弹警告 | 会 | 不显示警告消息 |
| 代价 | 无(对用户而言,什么都不用做) | 每次都要你主动点一下 |
看懂这张表,你就明白那个常被误传的说法为什么错:「装的时候没弹权限警告,说明它很干净。」不弹警告有两种可能:一种是它确实什么敏感权限都没要;另一种是它用的是 activeTab 这类「按需授权」的模式,能力一点不少,只是把授权拆成了很多次,每次都由你亲手触发。
警告框的有无,反映的是授权的时机,不是能力的大小。
五、进不去的地方,和要单独授的地方
5.1chrome://一律进不去
官方文档在讲受限页面时只给了一句:「无法访问受限页面,例如chrome://页面。」
这一句挡住的范围比看上去大。浏览器的设置页、扩展管理页、下载列表、历史记录,都在这一类地址下。也就是说,一个插件无论申请了多大的主机权限,它都碰不到「浏览器自己」的这些界面。
这条对你的实际用处是:当你怀疑某个插件在改浏览器设置时,可以先想一下——它做不到直接改chrome://下的页面。真出了变化,多半是走了设置类接口,而不是「在你的设置页里动手」。这两者的区别,决定了你该去哪个地方查。
5.2file://和无痕要单独授
本地文件和隐私窗口是另外两扇门,默认是关着的。官方原文:「如果您的扩展程序需要在file://网址上运行或在无痕模式下运行,用户必须在扩展程序的详情页面上授予该扩展程序访问权限」。
这里有个细节值得记住:这两项不是装的时候给的,是要你事后到详情页里单独打开。而且插件自己可以检测你有没有开——文档给了两个接口,extension.isAllowedIncognitoAccess()和isAllowedFileSchemeAccess()。
所以「我装了插件,但无痕窗口是干净的」这个印象需要修正:默认情况下插件在无痕里不生效,这是一条保护;但一旦你在详情页里给它开了,它在无痕里和普通窗口里没有区别。无痕模式保护的是本地记录,不是「插件看不见」。
5.3 一个三层过滤的判断顺序
拿到一个陌生插件,判断「它在某个页面上能不能动」,可以按这个顺序过:
| 层 | 问什么 | 结论 |
|---|---|---|
| 第一层 | 这个地址是不是chrome://之类的受限页 | 是 → 一律进不去,后面不用问 |
| 第二层 | 是不是file://本地文件 | 是 → 要你在详情页单独开过才行 |
| 第三层 | 当前窗口是不是无痕 | 是 → 同样要单独开过才行 |
| 第四层 | 它申请的是全站主机权限,还是 activeTab | 全站 → 直接可用;activeTab → 要你点一下 |
四层过完,答案基本就定了。这个顺序的好处是:前三层是硬边界,跟插件写得好不好无关,先排除掉能省很多事。
⚠️代码待验证
受限页 chrome:// → 停,一律进不去 file:// 本地文件 → 先看详情页有没有单独开过 无痕窗口 → 同样先看有没有单独开过 以上都不是 → 再看它是全站权限还是 activeTab受限页面这一节我整理成了一页对照表(哪些页面进不去、哪些要单独授、到哪儿去开):
六、自己怎么核:装前、装后、按需
6.1 装前:把清单读成一句话
清单不长,权限相关的就那两三行。下面两段是读清单的示意,用来说明字段长什么样,不是在教你写插件,也没有在真实插件上跑过。
第一段是「全站放行」的形态:
⚠️代码待验证
{"permissions":["tabs","cookies","scripting"],"host_permissions":["<all_urls>"]}读成一句话:它能读所有网站的网址和标题,能碰所有网站的 Cookie,能在所有网站里跑脚本。三个「所有」叠在一起,这就不算「网页增强」,而是「全局可见」。
第二段是「按需授权」的形态:
⚠️代码待验证
{"permissions":["activeTab","scripting"]}读成一句话:它只在你点它的时候,对当前这一个页面动手。没有host_permissions,没有cookies,能力被压到了很小。
把这两段摆在一起,你就有了判断标准:清单里出现多少个「所有」,决定了你该用多严的眼光看它。一个取词翻译插件要<all_urls>,可能说得通;一个只在一个网站上用的插件要<all_urls>,就值得问一句为什么。
6.2 装后:去详情页看那一栏
装完之后,浏览器给了你一个复核入口:扩展的详情页里有一栏专门列它现在能访问哪些网站。中文界面里这一栏通常叫「网站访问权限」,具体措辞可能随版本不同,以你屏幕上看到的为准(截至 2026-10-24 的常见写法如此)。
这一栏比安装时那个框更有用,原因有两个:一是它是当前状态,插件升级加过权限的话,这里会变;二是它通常带一个下拉,能让你把「在所有网站上」改成「在特定网站上」或者「点击时」。
所以装完不要就完了。花二十秒打开这一栏,看一眼写的是「在所有网站上」还是别的。这一步的成本极低,收益是把「我以为」换成「我看到了」。
6.3 按需开启,而不是全站放行
官方文档在讲最小权限时给了两句很实在的话:「如果扩展程序受到恶意软件的入侵,权限有助于限制损害。」以及「请考虑使用可选权限,以便用户在知情的情况下控制对资源和数据的访问权限」。
第一句是理由:权限的作用不是防止插件作恶,而是限定它作恶时的上限。一个只有当前页权限的插件被接管,损失是「这一页」;一个有全站权限的插件被接管,损失是「你打开过的所有页面」。同一份恶意代码,装在不同权限壳子里,后果差好几个量级。
第二句是做法:可选权限的设计意图,就是把「现在就要全部」改成「用到了再要」。它的清单形态大致是这样:
⚠️代码待验证
{"permissions":["activeTab"],"optional_host_permissions":["https://example.com/*"]}这表示装的时候只要当前页能力,某个具体域名的全站权限留到你真正需要时再开。对应到你的操作上,就是那个下拉框——能选「点击时」就别选「在所有网站上」,能限定到具体域名就别放开全站。
第三句是我加的:定期回头看一眼。装的时候判断过一次,不代表半年后还成立。插件会升级,清单会变,你访问的网站也会变。
七、三个误读,和本文不写的东西
7.1 三个常见误读
误读一:没弹权限警告,说明它很干净。第四章说过,activeTab 这类模式在安装期间不显示警告消息。不弹,只说明它没有申请「安装时就要报备」的那类权限,不说明它没有能力。
误读二:开源、评分高、下载多,就等于可信。这三项说的是「代码是否公开」「别人用得爽不爽」,都和「它申请了什么权限」是两个维度。一个完全开源、口碑很好的插件,照样可以申请<all_urls>加cookies;反过来,一个没人听说过的小插件也可能只要 activeTab。权限是事实,口碑是评价,别用评价代替事实。
误读三:我不用它的时候,它就停着。这要分两种模式说。activeTab 模式下确实如此,你不点它就没有授权。但主机权限是持久的——官方在对比时用的词是「对每个网站的完全持久访问权限」,持久两个字是重点:授权一次,之后不需要你每次同意。所以「我平时不点它」这句话,只对按需授权的插件成立。
7.2 警告文案我核不到,就不写
这一节是自我限制,请当成正文的一部分读。
安装时会弹出一个框,里面逐条写着每个权限对应的人话说明。这些说明的原文在另一份权限列表文档里,本批没有抓取核对。所以本文不引用任何一条警告文案,也不给你「看到这句话就要警惕」之类的对照表——那样写出来的东西看着有用,但每一条都可能是错的,而读者无从分辨。
能确定的只有一件事:安装时会弹一份权限清单,内容由清单字段生成。你要做的是把那份清单当成需要读的文本,而不是当成需要尽快点掉的弹窗。逐字文案的核对,留到有出处的时候再写。
7.3 本文的边界
这篇只做一件事:教你把清单读成「它能看见什么」,然后判断要不要装。
它不写怎么做一个能读取页面内容的插件——那是另一个方向的知识,和「判断要不要装」是相反的两件事。你学会了怎么造,不代表你学会了怎么防;而绝大多数读者需要的是后者。
另外三个相邻话题,本文也刻意避开了:浏览器本地存储怎么用、Cookie 的各项属性和作用域、以及内容安全策略与响应头。这三个都是独立的大题目,混进来会把「读清单」这条主线冲散。
这一节列的误读,加上前面几章的自查顺序,我做成了一张单页清单:
附表 A:本文引用事实与官方出处对照表
| 编号 | 事实摘要 | 出处 | 本文位置 |
|---|---|---|---|
| EXT-1 | "permissions":「包含来自已知字符串列表的项。更改可能会触发警告。」 | Chrome for Developers《声明权限》 | 1.3、2.1 |
| EXT-2 | "host_permissions":「包含一个或多个用于授予对一个或多个主机访问权限的匹配模式。」 | 同上 | 1.3、2.2 |
| EXT-3 | 「主机权限允许扩展程序与网址的匹配模式进行互动」,且「某些 Chrome API 还需要主机权限」 | 同上 | 2.2、2.3 |
| EXT-4 | 需要主机权限的六类动作(fetch、tabs 敏感属性、注入内容脚本、webRequest、cookies、declarativeNetRequest) | 同上 | 3.1–3.4 |
| EXT-5 | 三个例外:持tabs时用chrome.tabs、chrome.debugger、清单已声明的内容脚本 | 同上 | 3.5 |
| EXT-6 | activeTab 定义:「在用户调用扩展程序时临时访问当前活跃的标签页」 | 《activeTab 权限》 | 4.1 |
| EXT-7 | 四种触发手势:执行操作、上下文菜单项、Commands 快捷键、多功能框建议 | 同上 | 4.1 |
| EXT-8 | activeTab 下能做三件事:scripting注入、读 url/title/favicon、webRequest 拦截主框架请求 | 同上 | 4.2 |
| EXT-9 | 撤销规则:「在用户位于相应网页上时有效,并在用户离开或关闭标签页时被撤消」;同源子路径保留 | 同上 | 4.2 |
| EXT-10 | 可替代"<all_urls>"的许多用途,「但在安装期间不显示警告消息」 | 同上 | 4.3、7.1 |
| EXT-11 | 「无法访问受限页面,例如chrome://页面。」 | 同上 | 5.1 |
| EXT-12 | file://与无痕要在详情页单独授予;检测接口isAllowedIncognitoAccess()、isAllowedFileSchemeAccess() | 同上 | 5.2 |
| EXT-13 | 最小权限表述:「权限有助于限制损害」;「请考虑使用可选权限」 | 同上 | 6.3 |
| EXT-14 | 待验证:各权限对应的具体警告文案,本批未抓权限列表页 | — | 7.2(不引任何一条原文) |
| EXT-15 | 本文纪律:不写「做一个插件去读别人的内容」 | 本批纪律 | 7.3 |
| 补充 | 详情页栏目名称「网站访问权限」的具体措辞随版本可能变化 | 未逐字核对官方文案 | 6.2(已标"以屏幕为准") |
| 待验证 | 本文两段 JSON 为读清单的示意,未在真实插件上运行 | — | 6.1(代码待验证) |
附表 B:术语速查表
| 术语 | 含义 |
|---|---|
| 清单(manifest) | 插件根目录下由浏览器读取的配置文件,声明名称、入口与权限 |
| API 权限 | "permissions"里的项,决定能调用哪些浏览器接口 |
| 主机权限 | "host_permissions"里的项,决定上述接口能在哪些网址上生效 |
| 匹配模式 | 描述网址范围的规则,如https://example.com/*或<all_urls> |
<all_urls> | 覆盖所有支持协议的匹配模式,属于持久、全站的授权 |
| activeTab | 只在用户调用时临时授予当前标签页访问权的权限 |
| 用户调用 | 由你亲手触发的动作:点图标、选菜单、按快捷键、用地址栏建议 |
| 内容脚本 | 运行在网页上下文里的脚本,能读写该页面的 DOM |
| Service Worker | 插件的后台运行环境,可代你发起跨站请求 |
| webRequest | 观察并控制网络请求的接口,需主机权限配合 |
| declarativeNetRequest | 按规则重定向或改写请求的接口,同样依赖主机权限 |
| 受限页面 | 插件一律进不去的地址,如chrome://开头的页面 |
| 可选权限 | 不在安装时一并索取、由用户后续按需开启的权限 |
| 无痕访问 | 需用户在详情页单独授予,插件才能在隐私窗口里运行 |
写在最后:这篇用到的资料
写这篇文章时,我把浏览器里装过的插件一个个点开详情页,把「网站访问权限」那一栏抄下来对了一遍,顺手也整理了几份配套的东西:
- 靶场环境对照表:DVWA、upload-labs 在 Windows / macOS / Linux 三平台的可行性与推荐路径
- Web 安全学习路线图:从基础打牢到安全管理,四个阶段各学什么
- 常用靶场清单:每个靶场练什么、适合哪个阶段
资料是我自己整理的,放在下面这个码上,扫码即可获取:
添加时备注「靶场」,优先通过。
拿到之后建议先看环境对照表那一份,把「这个插件申请了几个所有」当成装任何扩展前的第一道门。