Skip to content
Closed
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
8 changes: 7 additions & 1 deletion src/wp-includes/media-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -1619,11 +1619,17 @@ function wp_print_media_templates() {
* The crossorigin attribute is added unconditionally to all relevant
* media tags to ensure cross-origin isolation works regardless of
* the final URL value at render time.
*
* IMG is intentionally excluded, matching wp_add_crossorigin_attributes().
* Under Document-Isolation-Policy: isolate-and-credentialless the browser
* loads cross-origin images in credentialless mode without CORS headers,
* so adding crossorigin="anonymous" would force a CORS request and break
* previews of images served without Access-Control-Allow-Origin headers.
*/
$template_processor = new WP_HTML_Tag_Processor( $script_processor->get_modifiable_text() );
while ( $template_processor->next_tag() ) {
if (
in_array( $template_processor->get_tag(), array( 'AUDIO', 'IMG', 'VIDEO' ), true )
in_array( $template_processor->get_tag(), array( 'AUDIO', 'VIDEO' ), true )
&& ! is_string( $template_processor->get_attribute( 'crossorigin' ) )
) {
$template_processor->set_attribute( 'crossorigin', 'anonymous' );
Expand Down
26 changes: 26 additions & 0 deletions tests/phpunit/tests/media/wpCrossOriginIsolation.php
Original file line number Diff line number Diff line change
Expand Up @@ -538,4 +538,30 @@ public function test_output_buffer_handles_mixed_tags() {
// Script and audio should have crossorigin.
$this->assertSame( 2, substr_count( $output, 'crossorigin="anonymous"' ), 'Script and audio should both get crossorigin, but not img.' );
}

/**
* IMG tags in the media manager templates must not receive
* crossorigin="anonymous", matching wp_add_crossorigin_attributes().
*
* Adding the attribute forces a CORS request that breaks previews of
* images served without Access-Control-Allow-Origin headers, such as
* media offloaded to a CDN.
*
* @ticket 65673
*
* @covers ::wp_print_media_templates
*/
public function test_print_media_templates_does_not_add_crossorigin_to_img() {
require_once ABSPATH . WPINC . '/media-template.php';

add_filter( 'wp_client_side_media_processing_enabled', '__return_true' );

ob_start();
wp_print_media_templates();
$output = ob_get_clean();

$this->assertMatchesRegularExpression( '/<img\b/i', $output, 'Expected the media templates to contain IMG tags.' );
$this->assertDoesNotMatchRegularExpression( '/<img\b[^>]*\bcrossorigin\b/i', $output, 'IMG tags in the media templates must not receive a crossorigin attribute.' );
$this->assertMatchesRegularExpression( '/<(?:audio|video)\b[^>]*crossorigin="anonymous"/i', $output, 'AUDIO and VIDEO tags in the media templates should still receive crossorigin="anonymous".' );
}
}
Loading