提高扩展程序的安全性

在 Manifest V3 中提高安全性

这是三个部分中的最后一部分,用于说明非扩展 Service Worker 的代码需要进行的更改。本文介绍了为提高扩展程序安全性而需要进行的更改。其他两个部分介绍了升级到 Manifest V3 所需的代码更新以及替换阻塞性 Web 请求。

移除任意字符串的执行

您将无法再使用 executeScript()、eval() 和 new Function() 执行外部逻辑。

  • 将所有外部代码(JS、Wasm、CSS)移至扩展程序软件包中。
  • 更新了脚本和样式引用,以从扩展程序软件包加载资源。
  • 使用 browser.runtime.getURL() 在运行时构建资源网址。
  • 使用沙盒化 iframe:沙盒化 iframe 仍支持 eval 和 new Function(...)。如需了解详情,请参阅有关沙盒 iframe 的指南。

executeScript() 方法现在位于 scripting 命名空间中,而不是 tabs 命名空间中。如需了解如何更新通话,请参阅移动 executeScript()。

在以下几种特殊情况下,仍然可以执行任意字符串:

移除远程托管的代码

在 Manifest V3 中,扩展程序的所有逻辑都必须是扩展程序软件包的一部分。根据 Chrome 应用商店政策,您现在无法再加载和执行远程托管的文件。例如:

  • 从开发者的服务器提取的 JavaScript 文件。
  • 托管在 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 数组。您仍然可以在运行时远程加载数据。

browser.scripting.executeScript({
  target: {tabId: tab.id},
  files: ['jquery-min.js', 'content-script.js']
});

注入函数

如果您需要更强的动态性,scripting.executeScript() 中的新 func 属性可让您注入函数作为内容脚本,并使用 args 属性传递变量。

Manifest V2
let name = 'World!';
browser.tabs.executeScript({
  code: `alert('Hello, ${name}!')`
});

在后台脚本文件中。

Manifest V3
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

function showAlert(givenName) {
  alert(`Hello, ${givenName}`);
}

let name = 'World';
browser.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"。

Manifest V2
{
  ...
  "content_security_policy": "default-src 'self'"
  ...
}
Manifest V3
{
  ...
  "content_security_policy": {
    "extension_pages": "default-src 'self'",
    "sandbox": "..."
  }
  ...
}

extension_pages:指扩展程序中的上下文,包括 HTML 文件和服务工作器。

sandbox:指扩展程序使用的任何沙盒化扩展程序页面。

移除不受支持的内容安全政策

Manifest V3 不允许在 "extension_pages" 字段中使用 Manifest V2 中允许的某些内容安全政策值。具体而言,Manifest V3 不允许使用那些允许远程代码执行的 API。script-src,、object-src 和 worker-src 指令只能具有以下值:

  • self
  • none
  • wasm-unsafe-eval
  • 仅限未打包的扩展程序:任何 localhost 来源(http://localhost、http://127.0.0.1 或这些网域上的任何端口)

sandbox 的内容安全政策值没有此类新限制。