Make WordPress Core

Changeset 55773


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

Grouped backports to the 6.0 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.
  • Editor: Remove shortcode support from block templates.

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

Location:
branches/6.0
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • branches/6.0/src/js/_enqueues/wp/embed.js

    r52132 r55773  
    5050        var iframes = document.querySelectorAll( 'iframe[data-secret="' + data.secret + '"]' ),
    5151            blockquotes = document.querySelectorAll( 'blockquote[data-secret="' + data.secret + '"]' ),
     52            allowedProtocols = new RegExp( '^https?:$', 'i' ),
    5253            i, source, height, sourceURL, targetURL;
    5354
     
    8485                sourceURL.href = source.getAttribute( 'src' );
    8586                targetURL.href = data.value;
     87
     88                /* Only follow link if the protocol is in the allow list. */
     89                if ( ! allowedProtocols.test( targetURL.protocol ) ) {
     90                    continue;
     91                }
    8692
    8793                /* Only continue if link hostname matches iframe's hostname. */
  • branches/6.0/src/js/media/views/frame/video-details.js

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

    r55372 r55773  
    4141            <div class="column">
    4242                <h2><?php _e( 'Maintenance and Security Releases' ); ?></h2>
     43                <p>
     44                    <?php
     45                    printf(
     46                        /* translators: %s: WordPress version number. */
     47                        __( '<strong>Version %s</strong> addressed some security issues.' ),
     48                        '6.0.4'
     49                    );
     50                    ?>
     51                    <?php
     52                    printf(
     53                        /* translators: %s: HelpHub URL. */
     54                        __( 'For more information, see <a href="%s">the release notes</a>.' ),
     55                        sprintf(
     56                            /* translators: %s: WordPress version. */
     57                            esc_url( __( 'https://wordpress.org/support/wordpress-version/version-%s/' ) ),
     58                            sanitize_title( '6.0.4' )
     59                        )
     60                    );
     61                    ?>
     62                </p>
    4363                <p>
    4464                    <?php
  • branches/6.0/src/wp-admin/includes/ajax-actions.php

    r54534 r55773  
    27432743    }
    27442744
     2745    if ( false === check_ajax_referer( 'set-attachment-thumbnail', '_ajax_nonce', false ) ) {
     2746        wp_send_json_error();
     2747    }
     2748
    27452749    $post_ids = array();
    27462750    // For each URL, try to find its corresponding post ID.
  • branches/6.0/src/wp-includes/block-template.php

    r53594 r55773  
    241241    $content = wptexturize( $content );
    242242    $content = convert_smilies( $content );
    243     $content = shortcode_unautop( $content );
    244243    $content = wp_filter_content_tags( $content );
    245     $content = do_shortcode( $content );
    246244    $content = str_replace( ']]>', ']]&gt;', $content );
    247245
  • branches/6.0/src/wp-includes/blocks.php

    r53923 r55773  
    648648    $result = '';
    649649
     650    if ( false !== strpos( $text, '<!--' ) && false !== strpos( $text, '--->' ) ) {
     651        $text = preg_replace_callback( '%<!--(.*?)--->%', '_filter_block_content_callback', $text );
     652    }
     653
    650654    $blocks = parse_blocks( $text );
    651655    foreach ( $blocks as $block ) {
     
    655659
    656660    return $result;
     661}
     662
     663/**
     664 * Callback used for regular expression replacement in filter_block_content().
     665 *
     666 * @private
     667 * @since 6.2.1
     668 *
     669 * @param array $matches Array of preg_replace_callback matches.
     670 * @return string Replacement string.
     671 */
     672function _filter_block_content_callback( $matches ) {
     673    return '<!--' . rtrim( $matches[1], '-' ) . '-->';
    657674}
    658675
  • branches/6.0/src/wp-includes/formatting.php

    r53204 r55773  
    24212421
    24222422/**
     2423 * Strips out all characters not allowed in a locale name.
     2424 *
     2425 * @since 6.2.1
     2426 *
     2427 * @param string $locale_name The locale name to be sanitized.
     2428 * @return string The sanitized value.
     2429 */
     2430function sanitize_locale_name( $locale_name ) {
     2431    // Limit to A-Z, a-z, 0-9, '_', '-'.
     2432    $sanitized = preg_replace( '/[^A-Za-z0-9_-]/', '', $locale_name );
     2433
     2434    /**
     2435     * Filters a sanitized locale name string.
     2436     *
     2437     * @since 6.2.1
     2438     *
     2439     * @param string $sanitized   The sanitized locale name.
     2440     * @param string $locale_name The locale name before sanitization.
     2441     */
     2442    return apply_filters( 'sanitize_locale_name', $sanitized, $locale_name );
     2443}
     2444
     2445/**
    24232446 * Converts lone & characters into `&#038;` (a.k.a. `&amp;`)
    24242447 *
  • branches/6.0/src/wp-includes/l10n.php

    r53060 r55773  
    148148
    149149    if ( ! empty( $_GET['wp_lang'] ) ) {
    150         $wp_lang = sanitize_text_field( $_GET['wp_lang'] );
     150        $wp_lang = sanitize_locale_name( wp_unslash( $_GET['wp_lang'] ) );
    151151    } elseif ( ! empty( $_COOKIE['wp_lang'] ) ) {
    152         $wp_lang = sanitize_text_field( $_COOKIE['wp_lang'] );
     152        $wp_lang = sanitize_locale_name( wp_unslash( $_COOKIE['wp_lang'] ) );
    153153    }
    154154
  • branches/6.0/src/wp-includes/media.php

    r53149 r55773  
    44124412        'captions'          => ! apply_filters( 'disable_captions', '' ),
    44134413        'nonce'             => array(
    4414             'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
     4414            'sendToEditor'           => wp_create_nonce( 'media-send-to-editor' ),
     4415            'setAttachmentThumbnail' => wp_create_nonce( 'set-attachment-thumbnail' ),
    44154416        ),
    44164417        'post'              => array(
  • branches/6.0/src/wp-includes/version.php

    r54628 r55773  
    1717 * @global string $wp_version
    1818 */
    19 $wp_version = '6.0.4-alpha-54628-src';
     19$wp_version = '6.0.4-src';
    2020
    2121/**
  • branches/6.0/tests/phpunit/tests/ajax/Attachments.php

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