Make WordPress Core

Changeset 55778


Ignore:
Timestamp:
05/16/2023 03:35:46 PM (17 months ago)
Author:
audrasjb
Message:

Grouped backports to the 5.7 branch.

  • Media: Prevent CSRF setting attachment thumbnails.
  • Embeds: Add protocol validation for WordPress Embed code.
  • I18N: Introduce sanitization function for locale.
  • Editor: Ensure block comments are of a valid form.

Merges [55760-55764] to the 5.7 branch.
Props dd32, isabel_brison, martinkrcho, matveb, ocean90, paulkevan, peterwilsoncc, timothyblynjacobs, xknown, youknowriad.

Location:
branches/5.7
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • branches/5.7/package-lock.json

    r54585 r55778  
    11{
    22    "name": "WordPress",
    3     "version": "5.7.8",
     3    "version": "5.7.9",
    44    "lockfileVersion": 1,
    55    "requires": true,
  • branches/5.7/package.json

    r54585 r55778  
    11{
    22    "name": "WordPress",
    3     "version": "5.7.8",
     3    "version": "5.7.9",
    44    "description": "WordPress is open source software you can use to create a beautiful website, blog, or app.",
    55    "repository": {
  • branches/5.7/src/js/_enqueues/wp/embed.js

    r46586 r55778  
    4545        var iframes = document.querySelectorAll( 'iframe[data-secret="' + data.secret + '"]' ),
    4646            blockquotes = document.querySelectorAll( 'blockquote[data-secret="' + data.secret + '"]' ),
     47            allowedProtocols = new RegExp( '^https?:$', 'i' ),
    4748            i, source, height, sourceURL, targetURL;
    4849
     
    7980                sourceURL.href = source.getAttribute( 'src' );
    8081                targetURL.href = data.value;
     82
     83                /* Only follow link if the protocol is in the allow list. */
     84                if ( ! allowedProtocols.test( targetURL.protocol ) ) {
     85                    continue;
     86                }
    8187
    8288                /* Only continue if link hostname matches iframe's hostname. */
  • branches/5.7/src/js/media/views/frame/video-details.js

    r43309 r55778  
    107107            wp.ajax.send( 'set-attachment-thumbnail', {
    108108                data : {
     109                    _ajax_nonce: wp.media.view.settings.nonce.setAttachmentThumbnail,
    109110                    urls: urls,
    110111                    thumbnail_id: attachment.get( 'id' )
  • branches/5.7/src/wp-admin/about.php

    r55375 r55778  
    7070            <div class="column has-border has-subtle-background-color">
    7171                <h2 class="is-smaller-heading"><?php _e( 'Maintenance and Security Releases' ); ?></h2>
     72                <p>
     73                    <?php
     74                    printf(
     75                        /* translators: %s: WordPress version number. */
     76                        __( '<strong>Version %s</strong> addressed some security issues.' ),
     77                        '5.7.9'
     78                    );
     79                    ?>
     80                    <?php
     81                    printf(
     82                        /* translators: %s: HelpHub URL. */
     83                        __( 'For more information, see <a href="%s">the release notes</a>.' ),
     84                        sprintf(
     85                            /* translators: %s: WordPress version. */
     86                            esc_url( __( 'https://wordpress.org/support/wordpress-version/version-%s/' ) ),
     87                            sanitize_title( '5.7.9' )
     88                        )
     89                    );
     90                    ?>
     91                </p>
     92
    7293                <p>
    7394                    <?php
  • branches/5.7/src/wp-admin/includes/ajax-actions.php

    r54553 r55778  
    27232723    }
    27242724
     2725    if ( false === check_ajax_referer( 'set-attachment-thumbnail', '_ajax_nonce', false ) ) {
     2726        wp_send_json_error();
     2727    }
     2728
    27252729    $post_ids = array();
    27262730    // For each URL, try to find its corresponding post ID.
  • branches/5.7/src/wp-includes/blocks.php

    r50419 r55778  
    565565    $result = '';
    566566
     567    if ( false !== strpos( $text, '<!--' ) && false !== strpos( $text, '--->' ) ) {
     568        $text = preg_replace_callback( '%<!--(.*?)--->%', '_filter_block_content_callback', $text );
     569    }
     570
    567571    $blocks = parse_blocks( $text );
    568572    foreach ( $blocks as $block ) {
     
    572576
    573577    return $result;
     578}
     579
     580/**
     581 * Callback used for regular expression replacement in filter_block_content().
     582 *
     583 * @private
     584 * @since 6.2.1
     585 *
     586 * @param array $matches Array of preg_replace_callback matches.
     587 * @return string Replacement string.
     588 */
     589function _filter_block_content_callback( $matches ) {
     590    return '<!--' . rtrim( $matches[1], '-' ) . '-->';
    574591}
    575592
  • branches/5.7/src/wp-includes/formatting.php

    r52466 r55778  
    23732373
    23742374/**
     2375 * Strips out all characters not allowed in a locale name.
     2376 *
     2377 * @since 6.2.1
     2378 *
     2379 * @param string $locale_name The locale name to be sanitized.
     2380 * @return string The sanitized value.
     2381 */
     2382function sanitize_locale_name( $locale_name ) {
     2383    // Limit to A-Z, a-z, 0-9, '_', '-'.
     2384    $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $locale_name );
     2385
     2386    /**
     2387     * Filters a sanitized locale name string.
     2388     *
     2389     * @since 6.2.1
     2390     *
     2391     * @param string $sanitized   The sanitized locale name.
     2392     * @param string $locale_name The locale name before sanitization.
     2393     */
     2394    return apply_filters( 'sanitize_locale_name', $sanitized, $locale_name );
     2395}
     2396
     2397/**
    23752398 * Converts lone & characters into `&#038;` (a.k.a. `&amp;`)
    23762399 *
  • branches/5.7/src/wp-includes/l10n.php

    r49963 r55778  
    146146
    147147    if ( ! empty( $_GET['wp_lang'] ) && ! empty( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] ) {
    148         $determined_locale = sanitize_text_field( $_GET['wp_lang'] );
     148        $determined_locale = sanitize_locale_name( wp_unslash( $_GET['wp_lang'] ) );
    149149    }
    150150
  • branches/5.7/src/wp-includes/media.php

    r50684 r55778  
    43094309        'captions'         => ! apply_filters( 'disable_captions', '' ),
    43104310        'nonce'            => array(
    4311             'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
     4311            'sendToEditor'           => wp_create_nonce( 'media-send-to-editor' ),
     4312            'setAttachmentThumbnail' => wp_create_nonce( 'set-attachment-thumbnail' ),
    43124313        ),
    43134314        'post'             => array(
  • branches/5.7/src/wp-includes/version.php

    r54585 r55778  
    1414 * @global string $wp_version
    1515 */
    16 $wp_version = '5.7.8-src';
     16$wp_version = '5.7.9-src';
    1717
    1818/**
  • branches/5.7/tests/phpunit/tests/ajax/Attachments.php

    r49835 r55778  
    116116        $this->assertSame( $expected, $response['data'] );
    117117    }
     118
     119    public function test_wp_ajax_set_attachment_thumbnail_success() {
     120        // Become an administrator.
     121        $post    = $_POST;
     122        $user_id = self::factory()->user->create(
     123            array(
     124                'role'       => 'administrator',
     125                'user_login' => 'user_36578_administrator',
     126                'user_email' => 'user_36578_administrator@example.com',
     127            )
     128        );
     129        wp_set_current_user( $user_id );
     130        $_POST = array_merge( $_POST, $post );
     131
     132        // Upload the attachment itself.
     133        $filename = DIR_TESTDATA . '/uploads/small-audio.mp3';
     134        $contents = file_get_contents( $filename );
     135
     136        $upload     = wp_upload_bits( wp_basename( $filename ), null, $contents );
     137        $attachment = $this->_make_attachment( $upload );
     138
     139        // Upload the thumbnail.
     140        $filename = DIR_TESTDATA . '/images/waffles.jpg';
     141        $contents = file_get_contents( $filename );
     142
     143        $upload    = wp_upload_bits( wp_basename( $filename ), null, $contents );
     144        $thumbnail = $this->_make_attachment( $upload );
     145
     146        // Set up a default request.
     147        $_POST['_ajax_nonce']  = wp_create_nonce( 'set-attachment-thumbnail' );
     148        $_POST['thumbnail_id'] = $thumbnail;
     149        $_POST['urls']         = array( wp_get_attachment_url( $attachment ) );
     150
     151        // Make the request.
     152        try {
     153            $this->_handleAjax( 'set-attachment-thumbnail' );
     154        } catch ( WPAjaxDieContinueException $e ) {
     155            unset( $e );
     156        }
     157
     158        // Get the response.
     159        $response = json_decode( $this->_last_response, true );
     160
     161        // Ensure everything is correct.
     162        $this->assertTrue( $response['success'] );
     163    }
     164
     165    public function test_wp_ajax_set_attachment_thumbnail_missing_nonce() {
     166        // Become an administrator.
     167        $post    = $_POST;
     168        $user_id = self::factory()->user->create(
     169            array(
     170                'role'       => 'administrator',
     171                'user_login' => 'user_36578_administrator',
     172                'user_email' => 'user_36578_administrator@example.com',
     173            )
     174        );
     175        wp_set_current_user( $user_id );
     176        $_POST = array_merge( $_POST, $post );
     177
     178        // Upload the attachment itself.
     179        $filename = DIR_TESTDATA . '/uploads/small-audio.mp3';
     180        $contents = file_get_contents( $filename );
     181
     182        $upload     = wp_upload_bits( wp_basename( $filename ), null, $contents );
     183        $attachment = $this->_make_attachment( $upload );
     184
     185        // Upload the thumbnail.
     186        $filename = DIR_TESTDATA . '/images/waffles.jpg';
     187        $contents = file_get_contents( $filename );
     188
     189        $upload    = wp_upload_bits( wp_basename( $filename ), null, $contents );
     190        $thumbnail = $this->_make_attachment( $upload );
     191
     192        // Set up a default request.
     193        $_POST['thumbnail_id'] = $thumbnail;
     194        $_POST['urls']         = array( wp_get_attachment_url( $attachment ) );
     195
     196        // Make the request.
     197        try {
     198            $this->_handleAjax( 'set-attachment-thumbnail' );
     199        } catch ( WPAjaxDieContinueException $e ) {
     200            unset( $e );
     201        }
     202
     203        // Get the response.
     204        $response = json_decode( $this->_last_response, true );
     205
     206        // Check that success is false without sending nonce.
     207        $this->assertFalse( $response['success'] );
     208    }
    118209}
Note: See TracChangeset for help on using the changeset viewer.