Service Worker防篡改需强制HTTPS、禁用动态生成、用SRI校验哈希、不缓存HTML、激活时清理旧缓存并claim控制权。

Service Worker 本身不是安全运行时,但它可以成为前端防篡改体系中的关键一环——前提是它不被篡改。真正的“防篡改”不靠加密或混淆,而靠加载可信、不可变、可验证的脚本,并切断所有可能被污染的路径。
必须强制 HTTPS,且拒绝降级
Service Worker 只能在安全上下文中注册和运行。浏览器规范明确要求:生产环境必须使用 HTTPS,否则注册直接失败。本地开发(localhost、127.0.0.1)是唯一例外,但上线后若走 HTTP,SW 将完全失效,且无法 fallback。
- 注册前务必校验协议:
if ('serviceWorker' in navigator && location.protocol === 'https:') - 禁止通过
document.write、eval或内联 script 动态生成 SW 脚本;SW 文件必须是静态、独立、带完整哈希摘要的资源 - 在服务器配置中禁用 HTTP → HTTPS 的 301 重定向用于 SW 注册路径(如
/sw.js),避免中间人利用重定向劫持
使用子资源完整性(SRI)锁定 SW 文件
即使 HTTPS 防止传输劫持,CDN 或代理仍可能返回被污染的 SW 脚本。SRI 是唯一能验证脚本内容未被修改的机制。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
- 构建时生成 SW 文件的 SHA-256 摘要,例如:
sha256-XyZ... - 注册时不直接调用
navigator.serviceWorker.register('/sw.js'),而是先 fetch 并校验哈希,再写入 blob URL 注册(规避 SRI 对register()的原生不支持限制) - 示例逻辑:
fetch('/sw.js').then(r => r.text()).then(text => { const hash = crypto.subtle.digest('SHA-256', new TextEncoder().encode(text)); if (hash !== EXPECTED_HASH) throw 'SW integrity check failed'; const blob = new Blob([text], {type: 'application/javascript'}); navigator.serviceWorker.register(URL.createObjectURL(blob)); });
缓存策略默认“不缓存 HTML”,避免离线劫持入口
HTML 是整个应用的入口点,也是最易被篡改的资源。若 Service Worker 缓存了 HTML,攻击者只需一次成功注入,就能长期控制后续所有访问。
立即学习“前端免费学习笔记(深入)”;
- 安装阶段明确排除 HTML 文件:
urlsToCache.filter(u => !u.endsWith('.html')) - fetch 拦截中对 HTML 请求始终 bypass cache:
if (request.destination === 'document') return fetch(request) - 如需离线首页,应使用固定、极简、无动态逻辑的
offline.html,且该文件本身由 SW 预置并禁止更新(版本固化)
激活阶段主动清理旧缓存 + 拒绝旧 SW 控制
旧版 Service Worker 若已接管页面,可能继续执行过期逻辑甚至恶意代码。激活时不仅要清理旧缓存,更要确保新 SW 立即获得控制权。
- activate 事件中调用
self.clients.claim(),使新 SW 立即接管当前页(无需关闭所有标签页) - 清除所有非当前版本的 cache:
caches.keys().then(keys => Promise.all(keys.map(k => k !== CACHE_NAME ? caches.delete(k) : null))) - 配合客户端检测:在页面 JS 中监听
controllerchange事件,发现 controller 更新后强制刷新(仅限关键安全策略变更场景)

















