Skip to content

Commit ce2c261

Browse files
Administration: Escape custom background page output
1 parent 7938204 commit ce2c261

2 files changed

Lines changed: 101 additions & 13 deletions

File tree

src/wp-admin/includes/class-custom-background.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ public function admin_page() {
247247
$message = sprintf(
248248
/* translators: %s: URL to background image configuration in Customizer. */
249249
__( 'You can now manage and live-preview Custom Backgrounds in the <a href="%s">Customizer</a>.' ),
250-
admin_url( 'customize.php?autofocus[control]=background_image' )
250+
esc_url( admin_url( 'customize.php?autofocus[control]=background_image' ) )
251251
);
252252
wp_admin_notice(
253253
$message,
@@ -308,7 +308,7 @@ public function admin_page() {
308308
. " background-attachment: $background_attachment;";
309309
}
310310
?>
311-
<div id="custom-background-image" style="<?php echo $background_styles; ?>"><?php // Must be double quote, see above. ?>
311+
<div id="custom-background-image" style="<?php echo esc_attr( $background_styles ); ?>"><?php // Must be double quote, see above. ?>
312312
<?php if ( $background_image_thumb ) { ?>
313313
<img class="custom-background-image" src="<?php echo $background_image_thumb; ?>" style="visibility:hidden;" alt="" /><br />
314314
<img class="custom-background-image" src="<?php echo $background_image_thumb; ?>" style="visibility:hidden;" alt="" />
@@ -431,16 +431,16 @@ public function admin_page() {
431431
);
432432
?>
433433
<tr>
434-
<th scope="row"><?php echo $background_position_title; ?></th>
435-
<td><fieldset><legend class="screen-reader-text"><span><?php echo $background_position_title; ?></span></legend>
434+
<th scope="row"><?php echo esc_html( $background_position_title ); ?></th>
435+
<td><fieldset><legend class="screen-reader-text"><span><?php echo esc_html( $background_position_title ); ?></span></legend>
436436
<div class="background-position-control">
437437
<?php foreach ( $background_position_options as $group ) : ?>
438438
<div class="button-group">
439439
<?php foreach ( $group as $value => $input ) : ?>
440440
<label>
441441
<input class="ui-helper-hidden-accessible" name="background-position" type="radio" value="<?php echo esc_attr( $value ); ?>"<?php checked( $value, $background_position ); ?>>
442442
<span class="button display-options position"><span class="<?php echo esc_attr( $input['icon'] ); ?>" aria-hidden="true"></span></span>
443-
<span class="screen-reader-text"><?php echo $input['label']; ?></span>
443+
<span class="screen-reader-text"><?php echo esc_html( $input['label'] ); ?></span>
444444
</label>
445445
<?php endforeach; ?>
446446
</div>
@@ -451,8 +451,8 @@ public function admin_page() {
451451

452452
<?php $image_size_title = __( 'Image Size' ); ?>
453453
<tr>
454-
<th scope="row"><label for="background-size"><?php echo $image_size_title; ?></label></th>
455-
<td><fieldset><legend class="screen-reader-text"><span><?php echo $image_size_title; ?></span></legend>
454+
<th scope="row"><label for="background-size"><?php echo esc_html( $image_size_title ); ?></label></th>
455+
<td><fieldset><legend class="screen-reader-text"><span><?php echo esc_html( $image_size_title ); ?></span></legend>
456456
<select id="background-size" name="background-size">
457457
<option value="auto"<?php selected( 'auto', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _ex( 'Original', 'Original Size' ); ?></option>
458458
<option value="contain"<?php selected( 'contain', get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ) ); ?>><?php _e( 'Fit to Screen' ); ?></option>
@@ -463,17 +463,17 @@ public function admin_page() {
463463

464464
<?php $background_repeat_title = _x( 'Repeat', 'Background Repeat' ); ?>
465465
<tr>
466-
<th scope="row"><?php echo $background_repeat_title; ?></th>
467-
<td><fieldset><legend class="screen-reader-text"><span><?php echo $background_repeat_title; ?></span></legend>
466+
<th scope="row"><?php echo esc_html( $background_repeat_title ); ?></th>
467+
<td><fieldset><legend class="screen-reader-text"><span><?php echo esc_html( $background_repeat_title ); ?></span></legend>
468468
<input name="background-repeat" type="hidden" value="no-repeat">
469469
<label><input type="checkbox" name="background-repeat" value="repeat"<?php checked( 'repeat', get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ) ); ?>> <?php _e( 'Repeat Background Image' ); ?></label>
470470
</fieldset></td>
471471
</tr>
472472

473473
<?php $background_scroll_title = _x( 'Scroll', 'Background Scroll' ); ?>
474474
<tr>
475-
<th scope="row"><?php echo $background_scroll_title; ?></th>
476-
<td><fieldset><legend class="screen-reader-text"><span><?php echo $background_scroll_title; ?></span></legend>
475+
<th scope="row"><?php echo esc_html( $background_scroll_title ); ?></th>
476+
<td><fieldset><legend class="screen-reader-text"><span><?php echo esc_html( $background_scroll_title ); ?></span></legend>
477477
<input name="background-attachment" type="hidden" value="fixed">
478478
<label><input name="background-attachment" type="checkbox" value="scroll" <?php checked( 'scroll', get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ) ); ?>> <?php _e( 'Scroll with Page' ); ?></label>
479479
</fieldset></td>
@@ -487,10 +487,10 @@ public function admin_page() {
487487
<?php
488488
$default_color = '';
489489
if ( current_theme_supports( 'custom-background', 'default-color' ) ) {
490-
$default_color = ' data-default-color="#' . esc_attr( get_theme_support( 'custom-background', 'default-color' ) ) . '"';
490+
$default_color = get_theme_support( 'custom-background', 'default-color' );
491491
}
492492
?>
493-
<input type="text" name="background-color" id="background-color" value="#<?php echo esc_attr( get_background_color() ); ?>"<?php echo $default_color; ?>>
493+
<input type="text" name="background-color" id="background-color" value="#<?php echo esc_attr( get_background_color() ); ?>"<?php if ( $default_color ) : ?> data-default-color="#<?php echo esc_attr( $default_color ); ?>"<?php endif; ?>>
494494
</fieldset></td>
495495
</tr>
496496
</tbody>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
/**
3+
* @group admin
4+
* @group themes
5+
*/
6+
7+
require_once ABSPATH . 'wp-admin/includes/class-custom-background.php';
8+
9+
class Tests_Admin_CustomBackground extends WP_UnitTestCase {
10+
/**
11+
* Administrator user ID.
12+
*
13+
* @var int
14+
*/
15+
private static $admin_id;
16+
17+
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
18+
self::$admin_id = $factory->user->create(
19+
array(
20+
'role' => 'administrator',
21+
)
22+
);
23+
}
24+
25+
public function set_up() {
26+
parent::set_up();
27+
28+
wp_set_current_user( self::$admin_id );
29+
set_current_screen( 'appearance_page_custom-background' );
30+
31+
remove_theme_support( 'custom-background' );
32+
add_theme_support(
33+
'custom-background',
34+
array(
35+
'default-position-x' => 'left',
36+
'default-position-y' => 'top',
37+
'default-size' => 'auto',
38+
'default-repeat' => 'repeat',
39+
'default-attachment' => 'scroll',
40+
)
41+
);
42+
}
43+
44+
public function tear_down() {
45+
remove_filter( 'theme_mod_background_position_x', array( $this, 'filter_background_position_x' ) );
46+
remove_theme_mod( 'background_image' );
47+
remove_theme_mod( 'background_image_thumb' );
48+
remove_theme_support( 'custom-background' );
49+
set_current_screen();
50+
wp_set_current_user( 0 );
51+
52+
parent::tear_down();
53+
}
54+
55+
/**
56+
* @ticket 57268
57+
*/
58+
public function test_admin_page_escapes_background_styles() {
59+
set_theme_mod( 'background_image', 'https://example.org/background.jpg' );
60+
set_theme_mod( 'background_image_thumb', 'https://example.org/background.jpg' );
61+
set_theme_mod( 'background_size', 'cover' );
62+
set_theme_mod( 'background_repeat', 'repeat' );
63+
set_theme_mod( 'background_attachment', 'scroll' );
64+
65+
add_filter( 'theme_mod_background_position_x', array( $this, 'filter_background_position_x' ) );
66+
67+
$custom_background = new Custom_Background();
68+
69+
ob_start();
70+
$custom_background->admin_page();
71+
$output = ob_get_clean();
72+
73+
$dom = new DOMDocument();
74+
75+
libxml_use_internal_errors( true );
76+
$dom->loadHTML( '<html><body>' . $output . '</body></html>' );
77+
libxml_clear_errors();
78+
79+
$image = $dom->getElementById( 'custom-background-image' );
80+
81+
$this->assertInstanceOf( DOMElement::class, $image );
82+
$this->assertFalse( $image->hasAttribute( 'onmouseover' ) );
83+
}
84+
85+
public function filter_background_position_x() {
86+
return 'left" onmouseover="alert(1)';
87+
}
88+
}

0 commit comments

Comments
 (0)