Description: Customize: Ignore invalid customization sessions.
 Fixes CVE-2017-9063 - A cross-site scripting (XSS) vulnerability
 was discovered related to the Customizer.
Author: ocean90@wordpress.org
Origin: upstream, https://core.trac.wordpress.org/changeset/40711
Applied-Upstream: 4.7.5
Reviewed-by: Craig Small <csmall@debian.org>
Last-Update: 2017-05-19
--- a/wp-admin/customize.php
+++ b/wp-admin/customize.php
@@ -149,7 +149,7 @@
 							echo sprintf( __( 'You are previewing %s' ), '<strong class="theme-name">' . $wp_customize->theme()->display('Name') . '</strong>' );
 						} else {
 							/* translators: %s is the site/panel title in the Customize pane */
-							echo sprintf( __( 'You are customizing %s' ), '<strong class="theme-name site-title">' . get_bloginfo( 'name' ) . '</strong>' );
+							echo sprintf( __( 'You are customizing %s' ), '<strong class="theme-name site-title">' . get_bloginfo( 'name', 'display' ) . '</strong>' );
 						}
 					?></span>
 				</div>
--- a/wp-admin/js/customize-controls.js
+++ b/wp-admin/js/customize-controls.js
@@ -2003,6 +2003,16 @@
 			}
 		});
 
+		// Ensure preview nonce is included with every customized request, to allow post data to be read.
+		$.ajaxPrefilter( function injectPreviewNonce( options ) {
+			if ( ! /wp_customize=on/.test( options.data ) ) {
+				return;
+			}
+			options.data += '&' + $.param({
+				customize_preview_nonce: api.settings.nonce.preview
+			});
+		});
+
 		// Refresh the nonces if the preview sends updated nonces over.
 		api.previewer.bind( 'nonce', function( nonce ) {
 			$.extend( this.nonce, nonce );
--- a/wp-includes/class-wp-customize-manager.php
+++ b/wp-includes/class-wp-customize-manager.php
@@ -175,6 +175,24 @@
 
 		$this->theme = wp_get_theme( isset( $_REQUEST['theme'] ) ? $_REQUEST['theme'] : null );
 
+		/*
+		 * Clear incoming post data if the user lacks a CSRF token (nonce). Note that the customizer
+		 * application will inject the customize_preview_nonce query parameter into all Ajax requests.
+		 * For similar behavior elsewhere in WordPress, see rest_cookie_check_errors() which logs out
+		 * a user when a valid nonce isn't present.
+		 */
+		$has_post_data_nonce = (
+			check_ajax_referer( 'preview-customize_' . $this->get_stylesheet(), 'nonce', false )
+			||
+			check_ajax_referer( 'save-customize_' . $this->get_stylesheet(), 'nonce', false )
+			||
+			check_ajax_referer( 'preview-customize_' . $this->get_stylesheet(), 'customize_preview_nonce', false )
+		);
+		if ( ! $has_post_data_nonce ) {
+			unset( $_POST['customized'] );
+			unset( $_REQUEST['customized'] );
+		}
+
 		if ( $this->is_theme_active() ) {
 			// Once the theme is loaded, we'll validate it.
 			add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) );
