Повышение безопасности расширений

Повышение уровня безопасности в Manifest V3

Это последний из трех разделов, описывающих изменения, необходимые для кода, не являющегося частью обработчика службы расширения. В нем описываются изменения, необходимые для повышения безопасности расширений. Два других раздела посвящены обновлению кода, необходимого для перехода на Manifest V3, и замене блокирующих веб-запросов .

Запретить выполнение произвольных строк

Вы больше не можете выполнять внешнюю логику с помощью executeScript() , eval() и new Function() .

  • Переместите весь внешний код (JS, Wasm, CSS) в пакет расширения.
  • Обновите ссылки на скрипты и стили, чтобы загружать ресурсы из пакета расширений.
  • Используйте chrome.runtime.getURL() для создания URL-адресов ресурсов во время выполнения.
  • Используйте iframe в изолированной среде: eval и new Function(...) по-прежнему поддерживаются в iframe в изолированной среде. Для получения более подробной информации ознакомьтесь с руководством по iframe в изолированной среде .

Метод executeScript() теперь находится в пространстве имен scripting , а не tabs . Информацию об обновлении вызовов см. в разделе «Перемещение executeScript() .

Существует несколько особых случаев, когда выполнение произвольных строк по-прежнему возможно:

Удалите удаленно размещенный код

В Manifest V3 вся логика вашего расширения должна быть частью пакета расширения. В соответствии с политикой Chrome Web Store , вы больше не можете загружать и выполнять удаленно размещенные файлы. Примеры включают:

  • Файлы JavaScript загружаются с сервера разработчика.
  • Любая библиотека, размещенная на CDN .
  • Встроенные сторонние библиотеки, которые динамически загружают удаленно размещенный код.

В зависимости от вашего сценария использования и причины удаленного размещения кода доступны альтернативные подходы. В этом разделе описаны подходы, которые следует рассмотреть. Если у вас возникли проблемы с работой с удаленно размещенным кодом, вы можете воспользоваться нашими рекомендациями .

Функции и логика, управляемые конфигурацией

Ваше расширение загружает и кэширует удалённую конфигурацию (например, JSON-файл) во время выполнения. Кэшированная конфигурация определяет, какие функции будут включены.

Внешняя логика с удаленным сервисом

Ваше расширение обращается к удалённому веб-сервису. Это позволяет сохранять код в тайне и изменять его по мере необходимости, избегая дополнительных затрат на повторную отправку в Chrome Web Store.

Встраивание удаленно размещенного кода в изолированную iframe-панель.

Код, размещенный удаленно, поддерживается в изолированных iframe-элементах . Обратите внимание, что этот подход не работает, если код требует доступа к DOM-дереву встраиваемой страницы.

Включать в пакеты сторонние библиотеки

Если вы используете популярный фреймворк, такой как React или Bootstrap, который ранее загружался с внешнего сервера, вы можете скачать минифицированные файлы, добавить их в свой проект и импортировать локально. Например:

<script src="./react-dom.production.min.js"></script>
<link href="./bootstrap.min.css" rel="stylesheet">

Чтобы включить библиотеку в сервис-воркер, установите в манифесте параметр "background.type" в значение "module" и используйте оператор import .

Используйте внешние библиотеки в скриптах, внедряемых с помощью клавиши Tab.

Вы также можете загружать внешние библиотеки во время выполнения, добавляя их в массив files при вызове scripting.executeScript() . При этом вы по-прежнему можете загружать данные удаленно во время выполнения.

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

Внедрить функцию

Если вам нужна большая динамичность, новое свойство func в scripting.executeScript() позволяет внедрять функцию в качестве скрипта содержимого и передавать переменные с помощью свойства args .

Манифест V2
let name = 'World!';
chrome.tabs.executeScript({
  code: `alert('Hello, ${name}!')`
});

В фоновом скриптовом файле.

Манифест V3
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 Extension Samples содержится пример внедрения функций, который можно просмотреть пошагово. Пример использования функции getCurrentTab() можно найти в справочнике по этой функции.

Поищите другие обходные пути.

Если описанные выше подходы не помогают в вашем случае, вам, возможно, придётся либо найти альтернативное решение (например, перейти на другую библиотеку), либо найти другие способы использования функциональности библиотеки. Например, в случае с Google Analytics вы можете переключиться на протокол измерения Google вместо использования официальной удалённо размещённой версии JavaScript, как описано в нашем руководстве по Google Analytics 4 .

Обновите политику безопасности контента.

Параметр "content_security_policy" не был удален из файла manifest.json , но теперь это словарь, поддерживающий два свойства: "extension_pages" и "sandbox" .

Манифест V2
{
  ...
  "content_security_policy": "default-src 'self'"
  ...
}
Манифест V3
{
  ...
  "content_security_policy": {
    "extension_pages": "default-src 'self'",
    "sandbox": "..."
  }
  ...
}

extension_pages : Относится к контекстам в вашем расширении, включая HTML-файлы и сервис-воркеры.

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 таких новых ограничений нет.