Skip to content

fix(service-worker): verify event source before processing INITIALIZE message#68898

Draft
arturovt wants to merge 1 commit into
angular:mainfrom
arturovt:fix/service_worker_initialize_source
Draft

fix(service-worker): verify event source before processing INITIALIZE message#68898
arturovt wants to merge 1 commit into
angular:mainfrom
arturovt:fix/service_worker_initialize_source

Conversation

@arturovt
Copy link
Copy Markdown
Contributor

Previously, the INITIALIZE action in onMessage was handled before the isClient() guard, allowing any source — including cross-origin iframes or unknown MessagePort handles — to trigger SW initialization without verification.

The fix explicitly checks that the message source is either the SW's own registration or a legitimate client before proceeding with ensureInitialized.

Example of the previous behavior:

A cross-origin iframe with a postMessage handle to the SW could trigger initialization at an arbitrary time:

// attacker-controlled iframe on https://evil.com
navigator.serviceWorker.getRegistration('/').then(reg => {
  reg.active.postMessage({ action: 'INITIALIZE' });
});

This would bypass the isClient() check that guards all other actions and invoke ensureInitialized() from an untrusted source, racing with cache writes during first-load initialization.

After the fix, messages with action: 'INITIALIZE' are accepted only from the SW's own registration (self.registration.active/installing/waiting) or from a verified client. All other sources are silently dropped, consistent with how all other actions are handled.

@angular-robot angular-robot Bot added the area: service-worker Issues related to the @angular/service-worker package label May 23, 2026
@ngbot ngbot Bot added this to the Backlog milestone May 23, 2026
… message

Previously, the `INITIALIZE` action in `onMessage` was handled before the
`isClient()` guard, allowing any source — including cross-origin iframes or
unknown `MessagePort` handles — to trigger SW initialization without
verification.

The fix explicitly checks that the message source is either the SW's own
registration or a legitimate client before proceeding with `ensureInitialized`.

**Example of the previous behavior:**

A cross-origin iframe with a `postMessage` handle to the SW could trigger
initialization at an arbitrary time:

```js
// attacker-controlled iframe on https://evil.com
navigator.serviceWorker.getRegistration('/').then(reg => {
  reg.active.postMessage({ action: 'INITIALIZE' });
});
```

This would bypass the `isClient()` check that guards all other actions and
invoke `ensureInitialized()` from an untrusted source, racing with cache
writes during first-load initialization.

**After the fix**, messages with `action: 'INITIALIZE'` are accepted only
from the SW's own registration (`self.registration.active/installing/waiting`)
or from a verified client. All other sources are silently dropped, consistent
with how all other actions are handled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: service-worker Issues related to the @angular/service-worker package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant