При использовании Service Worker и библиотеки Workbox для кэширования ресурсов веб-приложений необходимо уделять особое внимание чувствительным данным. К чувствительным данным относятся токены авторизации, персональные сведения пользователей, результаты приватных API-запросов. Некорректное кэширование таких данных может привести к утечкам информации или нарушению политики безопасности приложения.
Workbox по умолчанию предоставляет высокоуровневые стратегии
кэширования: CacheFirst, NetworkFirst,
StaleWhileRevalidate, NetworkOnly и
CacheOnly. Для ресурсов, содержащих чувствительные данные,
следует отдавать предпочтение стратегиям, минимизирующим хранение на
стороне клиента.
Пример стратегии для приватного API:
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
registerRoute(
({url}) => url.pathname.startsWith('/api/private/'),
new NetworkOnly()
);
В данном случае запросы к /api/private/ всегда идут к
сети, исключая их попадание в кэш. Это предотвращает случайное хранение
личной информации в Service Worker кэше.
Если необходимо кэшировать чувствительные данные, следует внедрять
строгую фильтрацию по статусу ответа и содержимому. Workbox позволяет
использовать функцию cacheWillUpdate в настройках
стратегии.
Пример проверки кэша по HTTP-статусу:
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
registerRoute(
({url}) => url.pathname.startsWith('/api/sensitive/'),
new CacheFirst({
cacheName: 'sensitive-cache',
plugins: [
new CacheableResponsePlugin({
statuses: [200] // только успешные ответы можно кэшировать
})
]
})
);
В дополнение к HTTP-статусу может быть полезно проверять заголовки ответа или JSON-содержимое, чтобы исключить случайное кэширование конфиденциальной информации.
Для чувствительных данных критично устанавливать ограниченный срок
хранения. Workbox предоставляет плагин ExpirationPlugin,
позволяющий ограничивать количество элементов и возраст кэша.
Пример ограничения хранения:
import {ExpirationPlugin} from 'workbox-expiration';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(
({url}) => url.pathname.startsWith('/api/sensitive/'),
new StaleWhileRevalidate({
cacheName: 'sensitive-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 50, // максимум 50 объектов
maxAgeSeconds: 300 // срок хранения 5 минут
})
]
})
);
Это обеспечивает автоматическое удаление устаревших данных и предотвращает накопление конфиденциальной информации.
В случаях, когда необходимо хранить чувствительные данные в кэше для оффлайн-доступа, рекомендуется применять шифрование перед сохранением. Workbox не предоставляет встроенного шифрования, но можно использовать кастомный плагин:
import CryptoJS from 'crypto-js';
const encryptPlugin = {
cacheWillUpdate: async ({response}) => {
if (!response || response.status !== 200) return null;
const clonedResponse = response.clone();
const text = await clonedResponse.text();
const encryptedText = CryptoJS.AES.encrypt(text, 'secret-key').toString();
return new Response(encryptedText, {
headers: clonedResponse.headers
});
}
};
registerRoute(
({url}) => url.pathname.startsWith('/api/sensitive/'),
new CacheFirst({
cacheName: 'encrypted-cache',
plugins: [encryptPlugin]
})
);
При последующем извлечении данных необходимо их расшифровывать перед использованием.
Чувствительные данные часто передаются через query-параметры
(?token=...). Workbox позволяет использовать регулярные
выражения или функции для фильтрации URL и исключения их из
кэширования:
registerRoute(
({url}) => !url.searchParams.has('token'),
new StaleWhileRevalidate()
);
Это предотвращает попадание токенов и других секретных данных в кэш.
Для сложных сценариев рекомендуется комбинировать несколько стратегий и плагинов:
NetworkOnly для критически чувствительных
запросов;StaleWhileRevalidate с ограничением по времени и
шифрованием для полу-конфиденциальных данных;ExpirationPlugin для автоматической очистки устаревшего
кэша;CacheableResponsePlugin для фильтрации по статусу
ответа.Такой подход позволяет балансировать между производительностью приложения и безопасностью данных.
ExpirationPlugin или при
обновлении Service Worker.cacheName.Эти меры позволяют снизить риски утечки данных через Service Worker и обеспечить безопасное использование кэширования в приложениях на JavaScript с Workbox.