Skip to content

Enhance sandbox component to accept sandbox prop - #69617

Merged
obenland merged 2 commits into
WordPress:trunkfrom
Imran92:fix/iframe-sandbox-extend
Jul 27, 2026
Merged

obenland merged 2 commits into
WordPress:trunkfrom
Imran92:fix/iframe-sandbox-extend

Conversation

@Imran92

@Imran92 Imran92 commented Mar 19, 2025

Copy link
Copy Markdown
Contributor

What?

Adds an optional allowPopups prop to the SandBox component, letting consumers opt into allow-popups in the iframe's sandbox attribute.

Why?

The iframe in the SandBox component does not include allow-popups in its sandbox value. Because of this, links inside sandboxed content don't take users anywhere when clicked — the navigation is blocked.

Our actual goal is to use this in the Jetpack repo to fix the VideoPress blocks. Jetpack consumes the @wordpress/components npm library, so this needs to be released on npm before we can move on with the next part of the fix.

How?

Since this PR was opened, SandBox was significantly refactored (#77212) and is now split into two internal variants, dispatched via the allowSameOrigin prop:

  • IsolatedSandBox (default) — sandbox="allow-scripts allow-presentation". allow-same-origin was deliberately dropped for user-controlled content (e.g. the HTML block) as a security hardening.
  • SameOriginSandBox (allowSameOrigin) — sandbox="allow-scripts allow-same-origin allow-presentation", for server-fetched oEmbed previews.

Neither variant includes allow-popups. Rather than expose a raw sandbox string override — which would let a caller pass allow-same-origin back into the isolated, user-controlled variant and quietly undo that hardening — this PR adds a targeted, opt-in allowPopups?: boolean prop (@default false). When set, allow-popups is appended to whichever variant's default sandbox attribute. This keeps with trunk's boolean-flag design (alongside allowSameOrigin) and preserves the existing security guarantees.

Testing Instructions

  1. Check the code and tests.
  2. Make sure any block or other consumer of SandBox doesn't break (default behavior is unchanged when allowPopups is not passed).
  3. Render a SandBox with allowPopups and confirm the iframe's sandbox attribute includes allow-popups, and that a link inside the sandboxed content can open.

Testing Instructions for Keyboard

N/A

Screenshots or screencast

N/A

@Imran92
Imran92 requested a review from ajitbohra as a code owner March 19, 2025 02:34
@github-actions

github-actions Bot commented Mar 19, 2025

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: Imran92 <imranh920@git.wordpress.org>
Co-authored-by: obenland <obenland@git.wordpress.org>
Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: mirka <0mirka00@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@Mamaduka Mamaduka added [Type] Enhancement A suggestion for improvement. [Feature] UI Components Impacts or related to the UI component system labels Mar 19, 2025
@Mamaduka

Copy link
Copy Markdown
Member

Thanks, @Imran92!

The https://github.com/Automattic/videopress/issues/1217 link leads to 404 packages. Please don't use private links or dead links for other repositories as references.

@t-hamano t-hamano added the [Package] Components /packages/components label Mar 19, 2025
@Imran92

Imran92 commented Mar 19, 2025

Copy link
Copy Markdown
Contributor Author

Thanks @Mamaduka , I've removed the links

@obenland

Copy link
Copy Markdown
Member

I went ahead and refreshed the PR and update the approach to use allowPopups and not undo the changes from #77212.

@Mamaduka Would you be a good person to ask for a review of this PR?

@mirka

mirka commented Jun 25, 2026

Copy link
Copy Markdown
Member

I see there are many allow-* options that a consumer could want to customize. It doesn't seem practical to add new props for each one. Are popups indeed a very special case, or should the API account for the possibility of all the other allow-* options?

@Mamaduka

Copy link
Copy Markdown
Member

We could allow passing additional sandbox props, which will be merged into the existing ones. Enabling overriding the entire iframe sandbox prop is also an option, but it's probably better to keep the defaults.

@jsnajdr

jsnajdr commented Jun 25, 2026

Copy link
Copy Markdown
Member

We could allow passing additional sandbox props, which will be merged into the existing ones.

The sandbox prop syntax is very similar to className, even to the point that we could use clsx to build the value:

const sandbox = clsx( 'allow-scripts', 'allow-same-origin', 'allow-presentation', {
  'allow-popups': allowPopups,
} );

But handling such a string list inside the component is a bit unwieldy. We'd have to parse it, fork the behavior completely on presence of allow-same-origin, and add the allow-scripts and allow-presentation which are enabled by default. That's another issue: how to day that a token that's present by default should be disabled?

Just defining a new allowPopups prop is much easier. And we could also have allowScripts and allowPresentation that are true by default, but are overridable.

There is the downside that @mirka mentions: there are currently 14 allow-* tokens and new ones will be probably introduced. I think it's an OK compromise though.

@jsnajdr jsnajdr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think that API-design-wise the allowPopups prop is OK, although not ideal. I'm approving to signal that the entire PR is OK. But let's continue discussing if there are disagreements.

Comment thread packages/components/src/sandbox/types.ts Outdated
@obenland
obenland requested a review from Copilot June 25, 2026 18:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@obenland

Copy link
Copy Markdown
Member

let's continue discussing if there are disagreements.

@mirka @Mamaduka Any other thoughts before this can move forward?

@Mamaduka

Copy link
Copy Markdown
Member

The clsx suggestion by @jsnajdr will be a nice improvement.

I would prefer improving general support for allow-* tokens, but understand allowPopups is an easier route, and we don't really have requests for other tokens.

Let's rebase, resolve conflicts and pipe tokens through clsx. Then I think it's good to land.

@github-actions github-actions Bot added [Package] Deprecated packages/deprecated [Package] Blob /packages/blob [Package] Compose /packages/compose [Package] Core data /packages/core-data [Package] API fetch /packages/api-fetch [Package] HTML entities /packages/html-entities [Package] Viewport /packages/viewport [Package] DOM /packages/dom [Package] Keycodes /packages/keycodes [Package] Plugins /packages/plugins [Package] Blocks /packages/blocks [Package] Editor /packages/editor [Package] Redux Routine /packages/redux-routine [Package] Block library /packages/block-library [Package] Notices /packages/notices [Package] Token List /packages/token-list [Package] Format library /packages/format-library [Package] Rich text /packages/rich-text [Package] Block editor /packages/block-editor [Package] Edit Post /packages/edit-post [Package] Data Controls /packages/data-controls [Package] Priority Queue /packages/priority-queue [Package] Edit Widgets /packages/edit-widgets [Package] E2E Tests /packages/e2e-tests labels Jul 27, 2026
Imran92 and others added 2 commits July 26, 2026 21:30
Adds an allowPopups prop to the SandBox component so that content
inside the sandboxed iframe (e.g. embeds with links) can open new
browsing contexts. The token is off by default and is applied to both
the isolated and same-origin sandbox variants.

Co-authored-by: Konstantin Obenland <obenland@gmx.de>
The sandbox attribute is a space-separated token list, just like
className, so clsx expresses the conditional allow-popups token more
clearly than template-string concatenation. Suggested by @jsnajdr in
the PR review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@obenland

Copy link
Copy Markdown
Member

Thanks @Mamaduka! Clumsily rebased onto trunk, resolved the conflicts, and the sandbox attribute is now built with clsx in both sandbox variants.

@Mamaduka Mamaduka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good to me 🚢

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

Labels

[Feature] UI Components Impacts or related to the UI component system [Package] Components /packages/components [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants