Skip to content

chore: block cross-origin postMessage in preview iframe - #597

Merged
Mukesh-FN merged 1 commit into
mainfrom
UIUX-2123/bug-bounty-dom-xss-via-unvalidated-postmessage
Oct 12, 2026
Merged

Mukesh-FN merged 1 commit into
mainfrom
UIUX-2123/bug-bounty-dom-xss-via-unvalidated-postmessage

Conversation

@Mukesh-FN

Copy link
Copy Markdown
Contributor

What

Blocks cross-origin postMessage events in the Storybook preview (iframe.html) served at wave.free-now.com.

Media

N/A: no visual changes.

Why

Storybook's preview channel handles every storybook-channel message without checking the sender's origin. Any external site could open iframe.html in a popup and send updateStoryArgs to set arbitrary story args. Components that pass props through to the DOM, such as Box, would then render attacker-supplied HTML via dangerouslySetInnerHTML, running script on the wave.free-now.com origin.

  • The bug is in Storybook itself: it's in 7.6.20 (what we deploy) and still in 10.3.6, so upgrading won't fix it.
  • The manager page (index.html) isn't affected, because it only accepts messages from its own preview iframes.
  • The docs are hosted on GitHub Pages, so we can't fix this with response headers.

Relates to UIUX-2123 (Bug bounty: DOM XSS via Unvalidated postMessage).

How

  • Adds an inline script at the top of .storybook/preview-head.html that registers a capture-phase message listener. For any message whose origin isn't the page's own origin, it calls stopImmediatePropagation().
  • Storybook puts preview-head.html into the <head> of iframe.html before its bundles load, so this check always runs before Storybook's own listener.
  • Messages between the manager and the preview come from the same origin, so they still go through. We don't use Storybook composition (refs) or embed cross-origin iframes, so nothing we rely on is blocked.
  • The commit type is chore, so semantic-release won't publish a new @freenow/wave version. The docs site redeploys when this merges to main.

Tested in headless Chromium against the current production build (from gh-pages), with the attack sent from a separate origin:

  • Without the fix: the injected script runs
  • With the fix: no injection, and the story renders normally
  • With the fix: sidebar navigation and editing Controls still update the preview

@pkg-pr-new

pkg-pr-new Bot commented Oct 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@freenow/wave@597

commit: 6488342

@Mukesh-FN
Mukesh-FN merged commit bb00408 into main Oct 12, 2026
8 checks passed
@Mukesh-FN
Mukesh-FN deleted the UIUX-2123/bug-bounty-dom-xss-via-unvalidated-postmessage branch October 12, 2026 16:13
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.0.0-rc.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

github-actions Bot pushed a commit that referenced this pull request Oct 27, 2026
## 2.67.0 (2026-10-27)

* feat: add magnifier eye icon (#599) ([b2a83bf](b2a83bf)), closes [#599](#599)
* ci: pause merge-main while Wave 3 release candidates are on next (#598) ([34dd5e1](34dd5e1)), closes [#598](#598)
* chore: block cross-origin postMessage in preview iframe (#597) ([bb00408](bb00408)), closes [#597](#597)
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.67.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

1 participant