Skip to content

Harden review frame: drop popup/download rights, validate external hrefs - #37

Open
dacoldest wants to merge 1 commit into
petergyang:mainfrom
dacoldest:harden/frame-sandbox-and-external-scheme
Open

Harden review frame: drop popup/download rights, validate external hrefs#37
dacoldest wants to merge 1 commit into
petergyang:mainfrom
dacoldest:harden/frame-sandbox-and-external-scheme

Conversation

@dacoldest

Copy link
Copy Markdown

Two small hardening changes to the review chrome. Both turned up while I was reading through the frame policy before installing the skill, and both looked worth sending back rather than just patching locally.

Frame sandbox drops allow-popups and allow-downloads

The iframe renders artifacts that are untrusted by definition, and its sandbox granted popups and downloads. Neither appears to be needed.

allow-popups in particular is redundant with the design that is already there: sdk.js does not open external links itself, it posts eh:external to the chrome, and the chrome calls window.open. The frame already delegates popup-opening upward, so granting it the capability directly just widens what a hostile artifact can do to the reviewer. Nothing in the tree references downloads at all.

Remaining sandbox is allow-scripts allow-forms allow-modals, plus allow-same-origin for localhost reviews exactly as before.

eh:external validates the href before window.open

The handler passed msg.href straight through. The origin check is the only thing in front of it, so a compromised frame or a misconfigured policy could land a javascript: URL there, and it would execute on the chrome's origin next to the session token.

Rather than add a second URL-safety helper, this routes the href through the existing normalizeHref in editing.js. It already allowlists http/https/mailto/tel and already has coverage for javascript:, data:, vbscript:, and tab-obfuscated variants like java\tscript:. Reusing it keeps one place where scheme policy lives.

Tests

92/92 pass. Added one regression test asserting no review grants the frame popups or downloads, and confirmed it fails against the previous constant before keeping it, so a revert cannot pass silently.

Not changed

framePolicy still returns targetOrigin: "*" for file and Markdown reviews. Tightening that to "null" for the opaque-origin case might be worth considering, but it changes an existing asserted value and felt like your call rather than mine.

Happy to adjust or split this if you would prefer it in separate PRs.

The review iframe renders artifacts that are untrusted by definition, but
its sandbox granted allow-popups and allow-downloads. Neither is needed:
the SDK posts external links to the chrome over eh:external and the chrome
opens them, and nothing downloads. Removing both narrows what a malicious
artifact can do to the reviewer.

The eh:external handler also called window.open on an unvalidated href.
The origin check is the only thing in front of it, so a compromised frame
or a misconfigured policy could land a javascript: URL there, executing on
the chrome's origin alongside the session token. Route it through the
existing normalizeHref, which already allowlists http/https/mailto/tel and
is tested against javascript:, data:, vbscript: and tab-obfuscated
variants, rather than adding a second URL-safety helper to diverge from.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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