Skip to content

fix: restrict runtime and playground message dispatch - #3816

Merged
jrusso1020 merged 1 commit into
mainfrom
fix/security-message-dispatch
Sep 9, 2026
Merged

fix: restrict runtime and playground message dispatch#3816
jrusso1020 merged 1 commit into
mainfrom
fix/security-message-dispatch

Conversation

@jrusso1020

Copy link
Copy Markdown
Collaborator

Runtime and SDK playground messages currently index ordinary objects with message-controlled action names. Names such as __proto__ and hasOwnProperty can select inherited values and throw instead of being ignored. The playground also accepts messages from unrelated windows, allowing them to change preview selection, timing, and edits.

This change closes the related message-dispatch boundary:

Validation: 2,704 core tests and four playground tests pass; both new regression tests fail the prior implementation. The playground test exercises the real registered UI listener with current/replaced frames, inherited names and non-string coercion attempts. A real Chromium check confirms preview duration messages work while self/sibling and inherited/coerced types are ignored without exceptions. Core and playground typechecks, full workspace build, final core rebuild, lint/format and signed hooks pass.

No alert dismissals are requested. Verify the three PR-ref results and then main CodeQL closure after merge. Payload validation beyond the existing message contract is unchanged.

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 7c12a68285ecdb61dd424734992f3d1305adacbd.

packages/core/src/runtime/bridge.ts:57-90,135 follows the CodeQL recommendation directly: the fixed action registry is a Map, so inherited names cannot resolve, while every supported control remains registered. The existing parent/self sender gate still runs before payload/action inspection.

packages/sdk-playground/src/main.ts:1359-1365 independently enforces the playground contract: it resolves the current iframe on every event, rejects null/replaced/foreign senders, requires a primitive string type, and checks an own registered handler before dispatch. The sandboxed srcdoc bridge remains the sole intended sender; supported click/deselect/drag/duration/time actions are unchanged.

Verification: core bridge tests pass 34/34 locally; changed-file oxlint/oxfmt and git diff --check pass. The playground test could not run in the isolated worktree because Vite denies the shared GSAP symlink outside its filesystem allowlist, so I relied on the passing hosted playground/full Test lanes for that surface. Both unrelated hosted timeouts passed on unchanged-head retry. All eight required checks, Windows, full Test, viewport, regression shards, and exact merge-ref CodeQL analysis 1749532267 are green with zero open PR-ref alerts. #648/#611/#612 are code-fixed; no dismissals.

— Magi

Verdict: APPROVE
Reasoning: Both dispatch tables now enforce explicit ownership and the playground authenticates the live iframe before any side effect, while all native gates are green at the reviewed head.

@jrusso1020
jrusso1020 merged commit 05d7261 into main Sep 9, 2026
87 of 90 checks passed
@jrusso1020
jrusso1020 deleted the fix/security-message-dispatch branch September 9, 2026 17:57
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.

2 participants