Повышение безопасности в Manifest V3
Это последний из трех разделов, в которых описаны изменения, необходимые для кода, не являющегося частью service worker расширения. В нем описаны изменения, необходимые для повышения безопасности расширений. В двух других разделах рассказывается о том, как обновить код для перехода на Manifest V3 и заменить блокирующие веб-запросы.
Удаление выполнения произвольных строк
Вы больше не можете выполнять внешнюю логику с помощью executeScript(), eval() и new Function().
- Переместите весь внешний код (JS, Wasm, CSS) в пакет расширения.
- Обновите ссылки на скрипты и стили, чтобы ресурсы загружались из пакета расширения.
- Используйте
browser.runtime.getURL(), чтобы создавать URL ресурсов во время выполнения. - Используйте изолированное окно iframe: теги
evalиnew Function(...)по-прежнему поддерживаются в изолированных окнах iframe. Подробнее о фреймах iframe с изолированной средой…
Метод executeScript() теперь находится в пространстве имен scripting, а не в пространстве имен tabs. Информацию об обновлении вызовов можно найти в разделе Перенос executeScript().
Однако есть несколько особых случаев, когда выполнение произвольных строк все ещё возможно:
- Как внедрить в веб-страницу таблицы стилей, размещенные на удаленном сервере, с помощью insertCSS
- Для расширений, использующих
browser.devtools: inspectWindow.eval позволяет выполнять код JavaScript в контексте проверяемой страницы. - Расширения для отладки могут использовать browser.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.
Как использовать внешние библиотеки в скриптах, внедренных во вкладку
Вы также можете загружать внешние библиотеки во время выполнения, добавив их в массив files при вызове scripting.executeScript(). Вы по-прежнему можете загружать данные удаленно во время выполнения.
browser.scripting.executeScript({
target: {tabId: tab.id},
files: ['jquery-min.js', 'content-script.js']
});
Внедрить функцию
Если вам нужно больше динамики, новое свойство func в scripting.executeScript() позволяет внедрить функцию в качестве скрипта контента и передавать переменные с помощью свойства args.
let name = 'World!'; browser.tabs.executeScript({ code: `alert('Hello, ${name}!')` });
В файле фонового скрипта.
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 Аналитикой вы можете перейти на протокол Measurement Protocol от Google вместо того, чтобы использовать официальную версию JavaScript, размещенную на удаленном сервере, как описано в нашем руководстве по Google Аналитике 4.
Как обновить Content Security Policy
"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-файлы и сервисных работников.
sandbox – любые изолированные страницы расширения, которые использует ваше расширение.
Удалите неподдерживаемые правила в отношении безопасности контента
В Manifest V3 запрещены некоторые значения Content Security Policy в поле "extension_pages", которые были разрешены в Manifest V2. В частности, Manifest V3 запрещает использование кода, размещенного на удаленных серверах. Директивы script-src,, object-src и worker-src могут иметь только следующие значения:
selfnonewasm-unsafe-eval- Только для распакованных расширений: любой источник localhost (
http://localhost,http://127.0.0.1или любой порт в этих доменах).
Новые ограничения не распространяются на значения правил безопасности контента для тега sandbox.