v150 · security · workers · origins
Opaque origin for data: URLs
Chrome 150 assigns a unique opaque origin to Dedicated Workers and Shared Workers created from data: URLs, rather than inheriting the creator's origin. This aligns Chrome with the HTML specification, with Firefox, and with Safari, closing a same-origin access path from these workers to their creator's storage and channels.
at a glance
| Shipped in | Chrome 150 (Enabled by default) |
|---|---|
| Status | Enabled by default |
| Spec | HTML Living Standard — Worker settings object |
| Standards position (Firefox) | Shipped/Shipping |
| Standards position (Safari) | Shipped/Shipping |
| ChromeStatus | 6290352295247872 — Opaque origin for data: URLs |
why it exists
Before Chrome 150, a data: URL worker automatically inherited the same origin as the page that created it — for example, new Worker('data:text/javascript,...') from https://example.com ran with origin https://example.com. This meant the worker could:
- Open a
BroadcastChanneland receive messages from other same-origin pages. - Access same-origin
localStorage,indexedDB, and other storage. - Be used to exfiltrate data if the worker script came from untrusted input.
The HTML Living Standard (step 3 of the Worker settings object algorithm) specifies that workers created from opaque URLs such as data: should receive a unique opaque origin. Chrome 150 implements this. The worker still shares the same storage partition as its creator (so quota accounting is unchanged), but it no longer shares the creator's same-origin privileges.
what changes
| Context | Chrome 149 and earlier | Chrome 150+ |
|---|---|---|
new Worker('data:...') from https://example.com | Worker origin = https://example.com | Worker origin = unique opaque origin |
BroadcastChannel from that worker | Receives messages from same-origin pages | Isolated — no same-origin channel access |
| Same-origin storage access | Allowed (localStorage, indexedDB, etc.) | Blocked for cross-origin storage; partition preserved |
Shared Workers via data: URL | Inherited origin | Opaque origin |
example
// Before Chrome 150: worker inherited https://example.com origin.
// After Chrome 150: worker has a unique opaque origin.
const workerCode = `
// This BroadcastChannel will no longer receive messages from the
// parent page's origin in Chrome 150+ — the worker is now isolated.
const bc = new BroadcastChannel('updates');
bc.onmessage = (e) => console.log('received', e.data);
`;
const blob = new Blob([workerCode], { type: 'text/javascript' });
const url = URL.createObjectURL(blob); // blob: URLs retain creator origin
// ^ Use blob: URLs (still inherits origin) for workers that need same-origin access.
// data: URLs now produce opaque origins.
// Prefer blob: URLs when same-origin communication is intended:
const w = new Worker(url);
// data: URL workers are safe for sandboxed computation:
const sandboxed = new Worker('data:text/javascript,' + encodeURIComponent(workerCode));
// sandboxed.origin is opaque — can't reach parent's storage or channels.
Source: HTML Living Standard §Worker settings object
browser support
| Browser | Support | Notes |
|---|---|---|
| Chrome 150+ | Enabled by default | Desktop and mobile |
| Firefox | Shipped | Already uses opaque origins for data: URL workers |
| Safari | Shipped | Already uses opaque origins for data: URL workers |