Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/wp-includes/media.php
Original file line number Diff line number Diff line change
Expand Up @@ -6549,6 +6549,15 @@ function wp_set_up_cross_origin_isolation(): void {
return;
}

/*
* Skip when rendering the classic-theme home route, which shows the site
* preview in an iframe and must reach its `contentDocument` to neutralize
* interactive elements. DIP would block that same-origin access.
*/
if ( 'site-editor' === $screen->id && ! wp_is_block_theme() && ( ! isset( $_GET['p'] ) || '/' === $_GET['p'] ) ) {
return;
}

/*
* Skip when a third-party page builder overrides the block editor.
* DIP isolates the document into its own agent cluster,
Expand Down
115 changes: 115 additions & 0 deletions tests/phpunit/tests/media/wpCrossOriginIsolation.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,18 @@ class Tests_Media_wpCrossOriginIsolation extends WP_UnitTestCase {
*/
private ?string $original_get_action;

/**
* Original $_GET['p'] value.
*/
private ?string $original_get_p;

public function set_up() {
parent::set_up();
$this->original_user_agent = $_SERVER['HTTP_USER_AGENT'] ?? null;
$this->original_http_host = $_SERVER['HTTP_HOST'] ?? null;
$this->original_https = $_SERVER['HTTPS'] ?? null;
$this->original_get_action = $_GET['action'] ?? null;
$this->original_get_p = $_GET['p'] ?? null;
}

public function tear_down() {
Expand Down Expand Up @@ -63,11 +69,19 @@ public function tear_down() {
$_GET['action'] = $this->original_get_action;
}

if ( null === $this->original_get_p ) {
unset( $_GET['p'] );
} else {
$_GET['p'] = $this->original_get_p;
}

// Clean up any output buffers started during tests.
while ( ob_get_level() > 1 ) {
ob_end_clean();
}

$GLOBALS['current_screen'] = null;

remove_all_filters( 'wp_client_side_media_processing_enabled' );
parent::tear_down();
}
Expand Down Expand Up @@ -159,6 +173,107 @@ public function test_does_not_start_output_buffer_for_safari() {
$this->assertSame( $level_before, $level_after, 'Output buffer should not be started for Safari.' );
}

/**
* The site editor home route on a classic theme skips DIP, because the
* editor renders the front end in a same-origin iframe and must reach its
* `contentDocument` to neutralize interactive elements. DIP would block
* that access.
*
* @ticket 65399
*
* @dataProvider data_classic_theme_site_editor_home_routes
*
* @param array $get The $_GET state representing the home route.
*/
public function test_skips_cross_origin_isolation_for_classic_theme_site_editor_home( array $get ) {
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36';
$_SERVER['HTTP_HOST'] = 'localhost';

wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
switch_theme( 'twentytwentyone' );
set_current_screen( 'site-editor' );

unset( $_GET['p'] );
foreach ( $get as $key => $value ) {
$_GET[ $key ] = $value;
}

$level_before = ob_get_level();
wp_set_up_cross_origin_isolation();
$level_after = ob_get_level();

$this->assertSame( $level_before, $level_after, 'DIP should be skipped on the classic-theme site editor home route.' );
}

/**
* Data provider for the classic-theme site editor home route.
*
* @return array[]
*/
public function data_classic_theme_site_editor_home_routes() {
return array(
'no p query var' => array( array() ),
'p query var is /' => array( array( 'p' => '/' ) ),
);
}

/**
* The site editor on a classic theme still sets up cross-origin isolation
* for routes other than the home route.
*
* @ticket 65399
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function test_sets_up_cross_origin_isolation_for_classic_theme_site_editor_non_home_route() {
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36';
$_SERVER['HTTP_HOST'] = 'localhost';

wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
switch_theme( 'twentytwentyone' );
set_current_screen( 'site-editor' );

$_GET['p'] = '/page/about';

$level_before = ob_get_level();
wp_set_up_cross_origin_isolation();
$level_after = ob_get_level();

$this->assertSame( $level_before + 1, $level_after, 'DIP should be set up on a non-home site editor route.' );

ob_end_clean();
}

/**
* The site editor on a block theme always sets up cross-origin isolation,
* including on the home route, because block themes do not render the
* classic site preview iframe.
*
* @ticket 65399
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function test_sets_up_cross_origin_isolation_for_block_theme_site_editor_home() {
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36';
$_SERVER['HTTP_HOST'] = 'localhost';

wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
switch_theme( 'twentytwentyfour' );
set_current_screen( 'site-editor' );

unset( $_GET['p'] );

$level_before = ob_get_level();
wp_set_up_cross_origin_isolation();
$level_after = ob_get_level();

$this->assertSame( $level_before + 1, $level_after, 'DIP should be set up on the block-theme site editor home route.' );

ob_end_clean();
}

/**
* @ticket 64803
*/
Expand Down
Loading