diff --git a/src/wp-admin/customize.php b/src/wp-admin/customize.php
index 9ce1f52812..ba4b5e6d24 100644
--- a/src/wp-admin/customize.php
+++ b/src/wp-admin/customize.php
@@ -144,7 +144,7 @@ do_action( 'customize_controls_print_scripts' );
' . get_bloginfo( 'name' ) . '' );
+ echo sprintf( __( 'You are customizing %s' ), '' . get_bloginfo( 'name', 'display' ) . '' );
?>
diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js
index c0ac1774af..c53f8cb82f 100644
--- a/src/wp-admin/js/customize-controls.js
+++ b/src/wp-admin/js/customize-controls.js
@@ -3227,6 +3227,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 );
diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php
index 9cac338591..3d6006f123 100644
--- a/src/wp-includes/class-wp-customize-manager.php
+++ b/src/wp-includes/class-wp-customize-manager.php
@@ -223,6 +223,24 @@ final class WP_Customize_Manager {
show_admin_bar( false );
+ /*
+ * 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 ( ! current_user_can( 'customize' ) ) {
$this->wp_die( -1 );
}