[wp-trac] [WordPress Trac] #65399: Skip Document-Isolation-Policy on the classic-theme site preview

WordPress Trac noreply at wordpress.org
Wed Jun 3 08:14:57 UTC 2026


#65399: Skip Document-Isolation-Policy on the classic-theme site preview
-----------------------------+-----------------------------
 Reporter:  adamsilverstein  |      Owner:  adamsilverstein
     Type:  defect (bug)     |     Status:  assigned
 Priority:  normal           |  Milestone:  7.1
Component:  Media            |    Version:
 Severity:  normal           |   Keywords:
  Focuses:                   |
-----------------------------+-----------------------------
 The site editor renders the front end of a '''classic theme''' inside a
 same-origin `?wp_site_preview=1` iframe. To neutralize the interactive
 elements of that preview (links, forms, etc.), the editor reads and
 manipulates the iframe's `contentDocument`.

 WordPress 7.1 sends a `Document-Isolation-Policy: isolate-and-
 credentialless` (DIP) header on block-editor screens (including the site
 editor) so that client-side media processing has access to
 `SharedArrayBuffer` and high-resolution timers. On Chromium 137+, DIP
 places the document into its own agent cluster. When the parent editor
 document is isolated but the same-origin preview iframe is not (or vice
 versa), the browser refuses cross-document `contentDocument` access, and
 neutralizing the classic-theme preview fails.

 == Steps to reproduce ==

 1. Activate a classic theme (for example, Twenty Twenty-One).
 2. In Chrome 137 or newer, open the Site Editor (`wp-admin/site-
 editor.php`).
 3. Observe the front-end site preview rendered in the iframe.

 '''Expected:''' The preview loads and its interactive elements are
 neutralized by the editor.

 '''Actual:''' The editor cannot reach the iframe's `contentDocument`
 because DIP has placed the editor in a separate agent cluster, so
 neutralization fails.

 == Proposed fix ==

 Skip cross-origin isolation in `wp_set_up_cross_origin_isolation()` for
 the classic-theme site editor '''home route''' only. The output buffer /
 DIP header is not started for that request, restoring same-origin
 `contentDocument` access.

 The guard is scoped narrowly:

 {{{#!php
 <?php
 if ( 'site-editor' === $screen->id && ! wp_is_block_theme() && ( ! isset(
 $_GET['p'] ) || '/' === $_GET['p'] ) ) {
         return;
 }
 }}}

 Behavior matrix:

 || '''Theme''' || '''Screen''' || '''Route''' || '''DIP''' ||
 || Classic || Site editor || Home (`p` unset or `/`) || '''Skipped''' ||
 || Classic || Site editor || Non-home (e.g. `p=/page/about`) || Applied ||
 || Block || Site editor || Any route || Applied ||

 Block themes do not render the classic site preview iframe, so they are
 unaffected. All non-home routes continue to receive DIP.

 == Patch ==

 * `src/wp-includes/media.php` — early return in
 `wp_set_up_cross_origin_isolation()` for the classic-theme site editor
 home route.
 * `tests/phpunit/tests/media/wpCrossOriginIsolation.php` — coverage for
 the skip (home route, `p` unset and `p=/`), and for DIP still being
 applied on classic-theme non-home routes and on block-theme routes.

 GitHub PR: https://github.com/WordPress/wordpress-develop/pull/12004

 == Related ==

 * Backport of [https://github.com/WordPress/gutenberg/pull/78404
 WordPress/gutenberg#78404].
 * Part of the 7.1 client-side media reintroduction:
 [https://github.com/WordPress/wordpress-develop/pull/11324 #11324].

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/65399>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list