提高 Manifest V3 的安全性
这是三部分的最后一部分,用于介绍不属于扩展 Service Worker 的代码需要进行的更改。其中介绍了需要做出哪些更改来提高扩展程序的安全性。另外两部分将介绍更新升级到 Manifest V3 所需的代码以及替换阻止网络请求的内容。
移除任意字符串的执行
您无法再使用 executeScript()
、eval()
和 new Function()
执行外部逻辑。
- 将所有外部代码(JS、Wasm、CSS)移至您的扩展程序软件包。
- 更新脚本和样式引用,以便从扩展程序包加载资源。
- 使用
chrome.runtime.getURL()
在运行时构建资源网址。 - 使用沙盒化 iframe:沙盒化 iframe 仍然支持
eval
和new Function(...)
。如需了解详情,请参阅有关沙盒化 iframe 的指南。
executeScript()
方法现在位于 scripting
命名空间中,而不是 tabs
命名空间中。如需了解如何更新调用,请参阅移动 executeScript()
。
在一些特殊情况下,仍然可以执行任意字符串:
- 使用 insertCSS 将远程托管的样式表注入网页
- 对于使用
chrome.devtools
的扩展程序:inspectWindow.eval 允许在被检查的页面上下文中执行 JavaScript。 - Debugger 扩展程序可以使用 chrome.debugger.sendCommand 在调试目标中执行 JavaScript。
移除远程托管代码
在 Manifest V3 中,扩展程序的所有逻辑都必须是扩展程序软件包的一部分。您无法再根据 Chrome 应用商店政策加载和执行远程托管文件。例如:
- 从开发者的服务器提取的 JavaScript 文件。
- 托管在 CDN 上的任何库。
- 可动态提取远程托管代码的捆绑第三方库。
您还可以使用其他方法,具体取决于您的使用场景和远程托管的原因。本部分介绍了可以考虑采用的方法。如果您在处理远程托管代码时遇到问题,可以参阅我们提供的相关指导。
配置驱动型功能和逻辑
您的扩展程序会在运行时加载并缓存远程配置(例如 JSON 文件)。缓存配置决定了启用哪些功能。
使用远程服务的外部化逻辑
您的扩展程序会调用远程网络服务。这样,您就可以确保代码的私密性并根据需要进行更改,同时避免向 Chrome 应用商店重新提交额外开销。
在沙盒化 iframe 中嵌入远程托管代码
沙盒化 iframe 支持远程托管代码。请注意,如果代码需要访问嵌入页面的 DOM,则无法使用此方法。
捆绑第三方库
如果您使用的是之前从外部服务器加载的热门框架(例如 React 或 Bootstrap),则可以下载压缩后的文件,将其添加到项目中并在本地导入。例如:
<script src="./react-dom.production.min.js"></script>
<link href="./bootstrap.min.css" rel="stylesheet">
如需在 Service Worker 中添加库,请在清单中将 "background.type"
键设置为 "module"
,并使用 import
语句。
在通过标签页注入的脚本中使用外部库
您还可以在调用 scripting.executeScript()
时将外部库添加到 files
数组中,从而在运行时加载这些库。您仍然可以在运行时远程加载数据。
chrome.scripting.executeScript({
target: {tabId: tab.id},
files: ['jquery-min.js', 'content-script.js']
});
注入函数
如果您需要提高动态性,scripting.executeScript()
中新增的 func
属性可让您注入函数作为内容脚本,并使用 args
属性传递变量。
let name = 'World!'; chrome.tabs.executeScript({ code: `alert('Hello, ${name}!')` });
async function getCurrentTab() {/* ... */} let tab = await getCurrentTab(); function showAlert(givenName) { alert(`Hello, ${givenName}`); } let name = 'World'; chrome.scripting.executeScript({ target: {tabId: tab.id}, func: showAlert, args: [name], });
Chrome 扩展程序示例代码库中包含一个函数注入示例,您可以逐步进行相关检查。getCurrentTab()
的一个示例位于该函数的引用中。
寻找其他解决方法
如果前面的方法对您的用例不起作用,您可能需要寻找替代解决方案(例如迁移到其他库)或找到使用该库功能的其他方法。例如,如果您使用 Google Analytics(分析),您可以改用 Google Measurement Protocol,而不是使用 Google Analytics(分析)4 指南中所述的官方远程托管 JavaScript 版本。
更新内容安全政策
"content_security_policy"
尚未从 manifest.json
文件中移除,但它现在是一个支持以下两个属性的字典:"extension_pages"
和 "sandbox"
。
{ ... "content_security_policy": "default-src 'self'" ... }
{ ... "content_security_policy": { "extension_pages": "default-src 'self'", "sandbox": "..." } ... }
extension_pages
:是指扩展程序中的上下文,包括 HTML 文件和 Service Worker。
sandbox
:是指您的扩展程序使用的所有沙盒化扩展程序页面。
移除不受支持的内容安全政策
Manifest V3 不允许在 "extension_pages"
字段中使用 Manifest V2 所允许的某些内容安全政策值。具体来说,Manifest V3 不允许使用那些允许远程执行代码的应用。script-src,
object-src
和 worker-src
指令只能包含以下值:
self
none
wasm-unsafe-eval
- 仅限未封装的扩展程序:任何 localhost 来源(
http://localhost
、http://127.0.0.1
或这些网域上的任何端口)
“sandbox
”的内容安全政策值没有此类新限制。