提高 Manifest V3 中的安全性
这是介绍非扩展程序 Service Worker 的代码所需更改的三个部分中的最后一部分。它介绍了为提高扩展程序的安全性而需要的更改。其他两个部分介绍了升级到 Manifest V3 所需的 代码更新,以及 替换阻塞性 Web 请求。
移除任意字符串的执行
您将无法再使用 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。 - 调试器扩展程序可以使用 chrome.debugger.sendCommand 在调试目标中执行 JavaScript。
移除远程托管的代码
在 Manifest V3 中,扩展程序的所有逻辑都必须是扩展程序软件包的一部分。根据 Chrome 应用商店政策,您将无法再加载和执行远程托管的文件。例如:
- 从开发者的服务器提取的 JavaScript 文件。
- CDN 上托管的任何CDN。
- 动态提取远程托管代码的捆绑式第三方库。
根据您的使用情形和远程托管的原因,有多种替代方法可供选择。本部分介绍了可考虑的方法。如果您在处理远程托管的代码时遇到问题,我们提供了相关指南。
配置驱动的功能和逻辑
您的扩展程序会在运行时加载并缓存远程配置(例如 JSON 文件)。缓存的配置决定了启用哪些功能。
使用远程服务外部化逻辑
您的扩展程序会调用远程 Web 服务。这样,您就可以将代码设为私有并根据需要进行更改,同时避免重新提交到 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], });
在后台 Service Worker 中。
Chrome 扩展程序示例代码库包含一个函数注入示例,您可以逐步了解。该函数的 参考 文档中提供了一个 getCurrentTab() 示例。
寻找其他变通方案
如果上述方法对您的使用情形没有帮助,您可能需要寻找替代解决方案(即迁移到其他库),或者寻找使用库功能的其他方法。例如,对于 Google Analytics,您可以切换到 Google Measurement Protocol,而不是使用官方远程托管的 JavaScript 版本,如我们的 Google Analytics 4 指南中所述。
更新内容安全政策
"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 指令只能具有以下值:
selfnonewasm-unsafe-eval- 仅限未打包的扩展程序:任何 localhost 来源(
http://localhost、http://127.0.0.1或这些网域上的任何端口)
sandbox 的内容安全政策值没有此类新限制。