Skip to content

fix(security): reject non-same-origin popout URLs#1266

Merged
mathuo merged 1 commit into
masterfrom
security/popout-url-validation
May 12, 2026
Merged

fix(security): reject non-same-origin popout URLs#1266
mathuo merged 1 commit into
masterfrom
security/popout-url-validation

Conversation

@mathuo
Copy link
Copy Markdown
Owner

@mathuo mathuo commented May 12, 2026

Summary

  • popoutUrl is round-tripped through layout JSON: toJSON() serializes the URL of each popout group, and fromJSON() restores it and feeds it back to window.open(). An attacker who can supply layout JSON could embed a javascript:, data:, blob:, or cross-origin URL that executes in a context the browser still associates with the opener via window.opener — exposing cookies, localStorage, and the parent DOM.
  • New exported assertSameOriginPopoutUrl runs at the PopoutWindow.open() gate and rejects anything that isn't same-origin http(s). The default /popout.html keeps working; existing dockview-core tests pass without change.
  • Adds a security caution to popoutGroups.mdx.

Breaking change (minor)

Consumers that intentionally pass a cross-origin popoutUrl will now see a thrown error. This is by design — that configuration was already unsafe — but worth flagging in release notes.

Test plan

  • npx nx test dockview-core — 893/893 pass, including 16 new assertSameOriginPopoutUrl cases covering: relative paths, same-origin absolute, javascript:, data:, blob:, vbscript:, file:, and cross-origin (host, port, scheme).
  • Manually open the demo and drag a panel into a popout — default /popout.html still works.
  • Manually call addPopoutGroup(group, { popoutUrl: 'javascript:alert(1)' }) and confirm it throws.

🤖 Generated with Claude Code

popoutUrl is round-tripped through layout JSON (toJSON serializes the
URL of each popout group; fromJSON restores it and feeds it back to
window.open). An attacker who can supply layout JSON could embed a
javascript:, data:, or cross-origin URL that would execute in a context
the browser still associates with the opener via window.opener,
exposing cookies, localStorage, and the parent DOM.

assertSameOriginPopoutUrl runs at the popout-window open() gate and
rejects anything that isn't same-origin http(s). The default
'/popout.html' still works; existing dockview-core tests pass without
change.

Also adds a security caution to the popout-groups documentation page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

@mathuo mathuo merged commit 179afb6 into master May 12, 2026
9 checks passed
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.

1 participant