Fix guide · low · service_worker_origin_wide_scope
Service Worker controls the entire origin (scope: '/')
A Service Worker registered at the origin root controls every page, every fetch, every cookie-bearing request on the site. It's the standard PWA template — but it widens the blast radius if the worker file is ever compromised.
Why it matters
This finding is informational rather than urgent. A worker at /sw.js with the default scope (/) is the vast majority of real-world Service Worker deploys, recommended by every PWA guide, and totally fine for normal operation.
The reason we surface it is blast radius:
- If the worker file is ever swapped (cache poisoning at your CDN, an attacker with write access to your build output, a misconfigured S3 bucket), every page on your origin executes the new code.
- If a route on your origin is compromised in a way that lets an attacker register a NEW worker (XSS, an evil sourcemap, a forgotten admin upload form), the new worker controls everything.
Narrowing the scope to the routes that actually need offline support reduces this risk:
// Instead of:
navigator.serviceWorker.register('/sw.js'); // controls everything
// Consider:
navigator.serviceWorker.register('/app/sw.js', { scope: '/app/' });
This way, the worker only controls /app/* routes. The rest of your origin (marketing pages, login flow, admin) is outside the worker's reach even if the worker file is malicious.
When narrowing scope is NOT worth the trouble:
- Pure SPAs where every page IS
/app/*already. - Sites where offline support is the entire product surface.
When it IS worth the trouble:
- Mixed sites (marketing site + product) — keep the worker out of the marketing scope.
- Sites with a separate auth/login flow — keep the worker out of
/login,/auth/*, etc.
How to fix it
Option A — narrow the scope (preferred when feasible):
- Move the SW file to a subdirectory:
/app/sw.js. - Register with explicit scope:
navigator.serviceWorker.register('/app/sw.js', { scope: '/app/' }). - Verify in DevTools → Application → Service Workers that scope is correct.
Option B — accept the wide scope but harden the worker file:
- Set strict caching headers on the SW file:
``http Cache-Control: no-cache `` This forces the browser to revalidate every load and prevents stale malicious copies from persisting.
- Add a deploy-time integrity check: store the SHA-256 of the deployed worker file and alert on drift.
- Set CSP
script-src 'self'so the worker can'timportScriptscross-origin code that turns same-origin → cross-origin compromise.
- Limit who can write to the build output. Shared dev access to the deploy bucket is the most common path to a compromised SW file.
Did vibecheck flag this on your app?
If you reached this page from a vibecheck inspection report, the redacted match in your scan output is the exact string we found in your bundle. After applying the fix above, run the inspection again — the finding should clear.
Run another inspection