Make WordPress Core

Changeset 55781


Ignore:
Timestamp:
05/16/2023 03:40:27 PM (14 months ago)
Author:
audrasjb
Message:

Grouped backports to the 5.6 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.6 branch.
Props dd32, isabel_brison, martinkrcho, matveb, ocean90, paulkevan, peterwilsoncc, timothyblynjacobs, xknown, youknowriad.

Location:
branches/5.6
Files:
1 added
12 edited

Legend:

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

    r54586 r55781  
    11{
    22    "name": "WordPress",
    3     "version": "5.6.10",
     3    "version": "5.6.11",
    44    "lockfileVersion": 1,
    55    "requires": true,
  • branches/5.6/package.json

    r54586 r55781  
    11{
    22    "name": "WordPress",
    3     "version": "5.6.10",
     3    "version": "5.6.11",
    44    "description": "WordPress is open source software you can use to create a beautiful website, blog, or app.",
    55    "repository": {
  • branches/5.6/src/js/_enqueues/wp/embed.js

    r46586 r55781  
    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.6/src/js/media/views/frame/video-details.js

    r43309 r55781  
    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.6/src/wp-admin/about.php

    r55376 r55781  
    8080                        /* translators: %s: WordPress version number */
    8181                        __( '<strong>Version %s</strong> addressed some security issues.' ),
     82                        '5.6.11'
     83                    );
     84                    ?>
     85                    <?php
     86                    printf(
     87                        /* translators: %s: HelpHub URL */
     88                        __( 'For more information, see <a href="%s">the release notes</a>.' ),
     89                        sprintf(
     90                            /* translators: %s: WordPress version */
     91                            esc_url( __( 'https://wordpress.org/support/wordpress-version/version-%s/' ) ),
     92                            sanitize_title( '5.6.11' )
     93                        )
     94                    );
     95                    ?>
     96                </p>
     97                <p>
     98                    <?php
     99                    printf(
     100                        /* translators: %s: WordPress version number */
     101                        __( '<strong>Version %s</strong> addressed some security issues.' ),
    82102                        '5.6.10'
    83103                    );
  • branches/5.6/src/wp-admin/includes/ajax-actions.php

    r54555 r55781  
    27242724    }
    27252725
     2726    if ( false === check_ajax_referer( 'set-attachment-thumbnail', '_ajax_nonce', false ) ) {
     2727        wp_send_json_error();
     2728    }
     2729
    27262730    $post_ids = array();
    27272731    // For each URL, try to find its corresponding post ID.
  • branches/5.6/src/wp-includes/blocks.php

    r49694 r55781  
    488488    $result = '';
    489489
     490    if ( false !== strpos( $text, '<!--' ) && false !== strpos( $text, '--->' ) ) {
     491        $text = preg_replace_callback( '%<!--(.*?)--->%', '_filter_block_content_callback', $text );
     492    }
     493
    490494    $blocks = parse_blocks( $text );
    491495    foreach ( $blocks as $block ) {
     
    495499
    496500    return $result;
     501}
     502
     503/**
     504 * Callback used for regular expression replacement in filter_block_content().
     505 *
     506 * @private
     507 * @since 6.2.1
     508 *
     509 * @param array $matches Array of preg_replace_callback matches.
     510 * @return string Replacement string.
     511 */
     512function _filter_block_content_callback( $matches ) {
     513    return '<!--' . rtrim( $matches[1], '-' ) . '-->';
    497514}
    498515
  • branches/5.6/src/wp-includes/formatting.php

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

    r49639 r55781  
    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.6/src/wp-includes/media.php

    r49995 r55781  
    42174217        'captions'         => ! apply_filters( 'disable_captions', '' ),
    42184218        'nonce'            => array(
    4219             'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
     4219            'sendToEditor'           => wp_create_nonce( 'media-send-to-editor' ),
     4220            'setAttachmentThumbnail' => wp_create_nonce( 'set-attachment-thumbnail' ),
    42204221        ),
    42214222        'post'             => array(
  • branches/5.6/src/wp-includes/version.php

    r54586 r55781  
    1414 * @global string $wp_version
    1515 */
    16 $wp_version = '5.6.10-src';
     16$wp_version = '5.6.11-src';
    1717
    1818/**
  • branches/5.6/tests/phpunit/tests/ajax/Attachments.php

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