Content Security Policy (CSP) — это механизм веб-безопасности, который позволяет контролировать, какие источники контента могут быть загружены веб-приложением. CSP предотвращает инъекции вредоносного кода и XSS-атаки, но при этом накладывает определённые ограничения на работу сервис-воркеров, особенно при использовании сторонних библиотек, таких как Workbox.
Workbox — это набор библиотек от Google, упрощающий создание прогрессивных веб-приложений (PWA) с сервис-воркерами. Он автоматизирует кеширование ресурсов, стратегий сетевого взаимодействия и управление версиями файлов. При интеграции с CSP необходимо учитывать несколько ключевых аспектов.
Запрет inline-скриптов CSP обычно блокирует
inline-скрипты ('unsafe-inline'), а также использование
eval(). Workbox в стандартной конфигурации может
генерировать inline-скрипты при автоматическом добавлении
precaching-манифеста или динамических обработчиков. Для корректной
работы необходимо использовать внешние файлы скриптов и избегать
inline-кода в сервис-воркере.
Разрешение источников Политика
script-src должна включать домены, с которых загружаются
скрипты воркера. В случае Workbox это чаще всего локальные скрипты или
файлы, сгенерированные инструментами сборки
(workbox-vX.X.X/workbox-sw.js). CSP-пример для Workbox:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.jsdelivr.net/npm/workbox-cdn@6.5.4/workbox-sw.js;
connect-src 'self' https:;
object-src 'none';
frame-ancestors 'none';Запрет eval() и new Function() Некоторые методы
Workbox, например workbox-build для генерации precache
manifest, используют динамическое создание функций. В продуктивной
сборке необходимо транспилировать и бандлить скрипты так, чтобы не
использовать eval().
Выделение воркера в отдельный файл Сервис-воркер должен регистрироваться как отдельный JS-файл. Пример регистрации:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('SW зарегистрирован:', registration);
})
.catch(error => {
console.error('Ошибка регистрации SW:', error);
});
});
}
CSP не будет блокировать загрузку файла, если он размещён на том же
домене ('self') или явно разрешён в
script-src.
Внешние библиотеки Workbox Workbox можно
подключить через CDN или включить в сборку. Использование CDN требует
явного разрешения домена в script-src. Рекомендуется
вариант с локальным бандлом для упрощения CSP и повышения
безопасности.
Precache и runtime caching Примеры конфигурации кеширования через Workbox:
import {precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
({request}) => request.destination === 'image',
new StaleWhileRevalidate({
cacheName: 'images-cache',
})
);
Здесь нет inline-функций, что совместимо с строгой CSP.
Workbox использует массив __WB_MANIFEST для предзагрузки
ресурсов. Этот массив генерируется на этапе сборки и должен быть встроен
в внешний файл воркера, а не в HTML. Если вставлять manifest inline, CSP
с 'unsafe-inline' запретит выполнение кода. Поэтому
правильный подход — использовать отдельный JS-файл, включающий
manifest:
// sw.js
import {precacheAndRoute} from 'workbox-precaching';
precacheAndRoute(self.__WB_MANIFEST);
Использование nonce Если inline-скрипты
неизбежны, CSP позволяет применять nonce:
script-src 'self' 'nonce-xyz123';
Скрипт должен иметь атрибут
<script nonce="xyz123">. Однако для сервис-воркеров
этот метод редко применяется, так как воркер регистрируется через
отдельный файл.
Использование strict-dynamic Политика
script-src 'strict-dynamic' позволяет загружать скрипты
через доверенные источники, игнорируя остальные правила
'self' и CDN. Комбинируется с nonce.
Бандлинг Workbox Интеграция через инструменты сборки (Webpack, Vite) позволяет генерировать единый JS-файл воркера, исключающий inline-код и eval. Это упрощает CSP и повышает безопасность.
eval().Если требуется, можно дополнительно рассмотреть конкретные кейсы конфигурации CSP для популярных сборщиков и Workbox-версий, с примерами production-ready setup, включая динамическое обновление сервис-воркера без нарушения политики безопасности.