Skip to content

worker-src

worker-src specifies valid sources for Worker, SharedWorker and ServiceWorker scripts.

Its fallback chain is the longest in CSP - worker-srcchild-srcscript-srcdefault-src - which is why a worker can be blocked by a policy that never mentions workers.

Content-Security-Policy: worker-src 'none';
Content-Security-Policy: worker-src <source-expression-list>;
  • new Worker(url).
  • new SharedWorker(url).
  • navigator.serviceWorker.register(url).

If worker-src is absent, the browser consults child-src, and then script-src, then default-src. The full chain is worker-srcchild-srcscript-srcdefault-src.

Content-Security-Policy: worker-src 'self' blob:
  • Bundlers routinely construct workers from a Blob, and blob: is not covered by 'self'. If your build does not do that, drop it.
  • A service worker must be same-origin anyway, so 'self' is rarely a constraint in practice - the violations you see here are almost always bundler-generated blob: workers.

Under worker-src 'self' blob::

const url = URL.createObjectURL(new Blob([src], { type: "text/javascript" }));
new Worker(url);

Under worker-src 'self':

new Worker("data:text/javascript,postMessage(1)");
  • Widely available across browsers since May 2022.
  • Before worker-src was available, workers were governed by child-src and then script-src. A policy that must support old browsers needs the fallbacks to agree with it.
Field Value
violatedDirective worker-src
effectiveDirective worker-src
blockedUri blob, https://cdn.example.com/worker.js, data
Issue title worker-src blob: URI
  • blockedUri: "blob" is the common case and groups into one issue per directive. It is a policy decision, not a bug hunt: either blob: belongs in worker-src or the bundler should emit a real file.
  • Service worker registration failures show up here with a same-origin URL, which usually means the fallback chain reached a script-src that does not include 'self'.

Point your policy’s report-uri at your site’s HeaderHawk endpoint and the violations above arrive in the dashboard, grouped as described. The Quick Start sets that up in five minutes, and the integration guides cover the header syntax for each platform.