Fix guide · critical · service_worker_cross_origin
Service Worker registered from a third-party host
Your page registers a Service Worker whose source is on a different origin. The third party can intercept every fetch your page makes — including auth headers, CSRF tokens, and response bodies — and reroute or modify the responses.
Why it matters
Service Workers operate as a programmable proxy that sits between your page and the network. Any worker registered on your origin can:
- See every fetch request the page makes, including the URL, method, and headers (cookies are NOT visible to the worker thanks to the same-origin restriction, BUT the worker can issue NEW fetches with credentials and read those responses).
- Replace any response with content of its choosing — including login pages, payment forms, or "your session has expired" UIs that exfiltrate retyped credentials.
- Persist data in the Cache API and IndexedDB long after the page is closed; on next visit the cached fake responses load instantly.
- Run for ~24 hours (or until the user manually clears site data) even if you fix the registration immediately.
When the worker source is cross-origin, the third party gets all of that. Even if their original code is benign, you've delegated full intercept-and-modify rights on your origin to whoever runs that host. If they're compromised, breached, sold, taken over by a state actor, or simply ship a buggy update — your users execute the result with full privileges.
This pattern shows up in three places we see in scans:
- Embeds from "free" tools — analytics, push notifications, A/B testing — that ask you to <code>register</code> their worker on your origin. The "convenience" is direct page-control delegation.
- Misconfigured CDNs — a build tool emitted <code>register("https://cdn.example.com/sw.js")</code> when it should have been a relative path; nobody noticed.
- Subresource subdomain confusion —
register("//assets.example.com/sw.js")thinking it's same-site; it's cross-origin.
How to fix it
- Unregister the cross-origin worker immediately. From the console, run:
``js navigator.serviceWorker.getRegistrations().then(rs => rs.forEach(r => r.unregister())); `` Then ship a server-side response that does the same on next page load (since users with the worker still cached won't visit the registration page).
- Self-host the worker. Whatever the third party was offering, host the file on your origin. Service Workers MUST be same-origin to register; the moment you set up a third-party SW, you've given the third party trust the same-origin policy was specifically designed to prevent.
- Add a CSP
worker-src 'self'directive to refuse cross-origin worker registration at the browser level:
``http Content-Security-Policy: worker-src 'self'; script-src 'self' ``
- Audit anything else from that vendor. A vendor that asks you to register a cross-origin worker has misjudged the trust boundary on at least one feature; assume they have similar misjudgments in others.
- Force-rotate any auth tokens issued during the worker's active lifetime. Even if no exfiltration is detected, treat it as compromised — the worker had read access to every response body returned to your users.
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