Skip to content

fix(web): validate kind on service-worker postMessage#431

Merged
intendednull merged 1 commit into
mainfrom
claude/issue-244-sw-postmessage-validate
Apr 27, 2026
Merged

fix(web): validate kind on service-worker postMessage#431
intendednull merged 1 commit into
mainfrom
claude/issue-244-sw-postmessage-validate

Conversation

@intendednull
Copy link
Copy Markdown
Owner

Why

navigator.serviceWorker.onmessage accepted whatever ev.data it got. payload landed on window.__willowLastPush — readable by any script in the page. no kind check before dispatching the in-app Notifier. defense-in-depth gap (SEC-W-06).

Fix

new service_worker_bridge module owns the SW boundary:

  • gate on kind in {willow-push, willow-notification-click} — anything else dropped silently. constants shared between writer (install) + reader (app.rs) so both ends agree in one place.
  • payload stashed in module-local thread_local! RefCell<Option<PushPayload>> (CLAUDE.md WASM single-thread rule), not on window. __willowLastPush write removed entirely — web is single-page, no second reader to keep alive.
  • validate_payload + store_and_dispatch split out so browser tests can drive the post-validation path without faking a ServiceWorker (unavailable under wasm-pack).

Verify

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo check -p willow-web --target wasm32-unknown-unknown
  • cargo test -p willow-web --lib
  • new wasm-pack tests cover: well-formed push accepted; notification-click accepted; missing kind dropped; wrong kind dropped; non-object dropped; round-trip fires willow-push event + drains slot

Closes #244


Generated by Claude Code

`navigator.serviceWorker.onmessage` previously accepted any payload
and stashed it on `window.__willowLastPush` — readable by any script
on the page and triggered the in-app Notifier without a kind check.

New `service_worker_bridge` module gates payloads on
`kind in {willow-push, willow-notification-click}` (constants shared
with the reader) and stores the result in a thread-local
`RefCell<Option<PushPayload>>` instead of a window property. The
global `__willowLastPush` write is removed entirely; web is a
single-page app with no other reader to keep compatible.

Closes #244
@intendednull intendednull merged commit 747e6f9 into main Apr 27, 2026
7 checks passed
@intendednull intendednull deleted the claude/issue-244-sw-postmessage-validate branch April 27, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SEC-W-06] Service-worker postMessage payload accepted without kind / origin check

2 participants