Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Theme Previews: Add a nonce for activation #4795

Closed
wants to merge 7 commits into from
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
7 changes: 0 additions & 7 deletions src/wp-admin/includes/admin-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,3 @@

// Append '(Draft)' to draft page titles in the privacy page dropdown.
add_filter( 'list_pages', '_wp_privacy_settings_filter_draft_page_titles', 10, 2 );

// Attaches filters to enable theme previews in the Site Editor.
if ( ! empty( $_GET['wp_theme_preview'] ) ) {
add_filter( 'stylesheet', 'wp_get_theme_preview_path' );
add_filter( 'template', 'wp_get_theme_preview_path' );
add_action( 'init', 'wp_attach_theme_preview_middleware' );
}
1 change: 0 additions & 1 deletion src/wp-admin/includes/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@

/** WordPress Theme Administration API */
require_once ABSPATH . 'wp-admin/includes/theme.php';
require_once ABSPATH . 'wp-admin/includes/theme-previews.php';

/** WordPress Privacy Functions */
require_once ABSPATH . 'wp-admin/includes/privacy-tools.php';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,31 @@ function wp_attach_theme_preview_middleware() {
'after'
);
}

/**
* Set a JavaScript constant for theme activation.
*
* Sets the JavaScript global WP_BLOCK_THEME_ACTIVATE_NONCE containing the nonce
* required to activate a theme. For use within the site editor.
*
* @see https://github.com/WordPress/gutenberg/pull/41836.
*
* @since 6.3.0
tellthemachines marked this conversation as resolved.
Show resolved Hide resolved
* @private
*/
function wp_block_theme_activate_nonce() {
$nonce_handle = 'switch-theme_' . wp_get_theme_preview_path();
Copy link

@anton-vlasenko anton-vlasenko Jul 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: I don't see many PHP frameworks using inline tags to output text these days. Instead, I would use echo or print to output the nonce code to the buffer. But I admit, this is just a personal preference.

?>
<script type="text/javascript">
window.WP_BLOCK_THEME_ACTIVATE_NONCE = '<?php echo wp_create_nonce( $nonce_handle ); ?>';
Copy link

@anton-vlasenko anton-vlasenko Jul 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could potentially be a security issue. Is there a specific reason for not escaping the nonce value?

Suggested change
window.WP_BLOCK_THEME_ACTIVATE_NONCE = '<?php echo wp_create_nonce( $nonce_handle ); ?>';
window.WP_BLOCK_THEME_ACTIVATE_NONCE = '<?php echo esc_js( wp_create_nonce( $nonce_handle ) ); ?>';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch @anton-vlasenko -- it's more a bug than a security issue as it's not user input, however it may break with custom nonce implementations using special characters.

It will need to change to = <?php echo wp_json_encode( wp_create_nonce( $nonce_handle ) ); (without quotes) as esc_js() is intended for use in DOM attributes.

wp> esc_js( 'Pens & Pencils' );
=>  string(18) "Pens &amp; Pencils"
wp> wp_json_encode( 'Pens & Pencils' );
=> string(16) ""Pens & Pencils""

I'll reopen the ticket and add a PR to the GB repo.

Copy link

@anton-vlasenko anton-vlasenko Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for getting back to my code review, @peterwilsoncc!

Yes, using wp_json_encode() is also an option.
In fact, I prefer wp_json_encode() over esc_js() because it automatically adds quotes.
I was just uncertain about which function aligns better with the "true WordPress way" of doing things.

</script>
<?php
}

// Attaches filters to enable theme previews in the Site Editor.
if ( ! empty( $_GET['wp_theme_preview'] ) ) {
add_filter( 'stylesheet', 'wp_get_theme_preview_path' );
add_filter( 'template', 'wp_get_theme_preview_path' );
add_action( 'init', 'wp_attach_theme_preview_middleware' );
add_action( 'admin_head', 'wp_block_theme_activate_nonce' );
}
1 change: 1 addition & 0 deletions src/wp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
require ABSPATH . WPINC . '/block-template-utils.php';
require ABSPATH . WPINC . '/block-template.php';
require ABSPATH . WPINC . '/theme-templates.php';
require ABSPATH . WPINC . '/theme-previews.php';
require ABSPATH . WPINC . '/template.php';
require ABSPATH . WPINC . '/https-detection.php';
require ABSPATH . WPINC . '/https-migration.php';
Expand Down