Make WordPress Core

Changeset 63110


Ignore:
Timestamp:
08/06/2026 07:52:36 PM (24 hours ago)
Author:
desrosj
Message:

Security: Backport the WordPress 7.0.3 security fixes to the 5.2 branch.

  • Users: Ensure a proper email address is used before sending email confirmations.
  • Formatting: Prevent stack overflow in safecss_filter_attr.
  • Multisite: Enforce the active signup policy for existing users.
  • HTTP API: Improve compliance with IPv4 Special-Purpose Address Space.
  • Users: Prevent Usernames from mangling HTML
  • Canonical: Only redirect for publicly viewable post types.
  • Administration: When wp_is_large_user_count(), ensure that the post author is always added to author dropdown.

Merges [63060],[63061],[63062],[63063],[63064],[63065],[63067] to the 5.2 branch.

Props xknown, westonruter, jeremyfelt, peterwilsoncc, paulkevan, lucasbustamante, jorbin, desrosj, vortfu, dmsnell, johnbillion, ehtis, batmoo, lancewillett, jonsurrell.

Location:
branches/5.2/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/5.2/src/js/_enqueues/admin/inline-edit-post.js

    r43577 r63110  
    274274
    275275                        // The post author no longer has edit capabilities, so we need to add them to the list of authors.
    276                         $(':input[name="post_author"]', editRow).prepend('<option value="' + $('.post_author', rowData).text() + '">' + $('#' + t.type + '-' + id + ' .author').text() + '</option>');
     276                        $(':input[name="post_author"]', editRow).prepend(
     277                                new Option(
     278                                        $('#' + t.type + '-' + id + ' .author').text(),
     279                                        $('.post_author', rowData).text()
     280                                )
     281                        );
    277282                }
    278283                if ( $( ':input[name="post_author"] option', editRow ).length === 1 ) {
  • branches/5.2/src/wp-admin/includes/user.php

    r45194 r63110  
    4545        }
    4646
     47        $errors = new WP_Error();
     48
    4749        $pass1 = $pass2 = '';
    4850        if ( isset( $_POST['pass1'] ) ) {
     
    7880
    7981        if ( isset( $_POST['email'] ) ) {
    80                 $user->user_email = sanitize_text_field( wp_unslash( $_POST['email'] ) );
     82                $maybe_email = wp_unslash( $_POST['email'] );
     83                if ( is_string( $maybe_email ) && is_email( $maybe_email ) ) {
     84                        $user->user_email = $maybe_email;
     85                } else {
     86                        $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ), array( 'form-field' => 'email' ) );
     87                }
    8188        }
    8289        if ( isset( $_POST['url'] ) ) {
     
    139146                $user->use_ssl = 1;
    140147        }
    141 
    142         $errors = new WP_Error();
    143148
    144149        /* checking that username has been typed */
  • branches/5.2/src/wp-includes/canonical.php

    r45133 r63110  
    665665
    666666        if ( get_query_var( 'name' ) ) {
     667                $publicly_viewable_post_types = array_filter( get_post_types( array( 'exclude_from_search' => false ) ), 'is_post_type_viewable' );
     668
    667669                $where = $wpdb->prepare( 'post_name LIKE %s', $wpdb->esc_like( get_query_var( 'name' ) ) . '%' );
    668670
    669671                // if any of post_type, year, monthnum, or day are set, use them to refine the query
    670672                if ( get_query_var( 'post_type' ) ) {
    671                         $where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
     673                        if ( is_array( get_query_var( 'post_type' ) ) ) {
     674                                $post_types = array_intersect( get_query_var( 'post_type' ), $publicly_viewable_post_types );
     675                                if ( empty( $post_types ) ) {
     676                                        return false;
     677                                }
     678                                $where .= " AND post_type IN ('" . implode( "', '", esc_sql( $post_types ) ) . "')";
     679                        } else {
     680                                if ( ! in_array( get_query_var( 'post_type' ), $publicly_viewable_post_types, true ) ) {
     681                                        return false;
     682                                }
     683                                $where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
     684                        }
    672685                } else {
    673                         $where .= " AND post_type IN ('" . implode( "', '", get_post_types( array( 'public' => true ) ) ) . "')";
     686                        $where .= " AND post_type IN ('" . implode( "', '", esc_sql( $publicly_viewable_post_types ) ) . "')";
    674687                }
    675688
  • branches/5.2/src/wp-includes/http.php

    r46480 r63110  
    561561                if ( $ip ) {
    562562                        $parts = array_map( 'intval', explode( '.', $ip ) );
    563                         if ( 127 === $parts[0] || 10 === $parts[0] || 0 === $parts[0]
    564                                 || ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
    565                                 || ( 192 === $parts[0] && 168 === $parts[1] )
     563
     564                        /*
     565                         * These IP address ranges are not considered valid external hosts for HTTP requests.
     566                         *
     567                         * If the host resolves to an IP address in these ranges, the request will be rejected unless the 'http_request_host_is_external' filter allows it.
     568                         *
     569                         * References:
     570                         *
     571                         * - IPv4 Special-Purpose Address Space: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
     572                         * - IPv4 Multicast Address Assignments: https://www.rfc-editor.org/rfc/rfc5771.html
     573                         */
     574                        if ( 127 === $parts[0] || 10 === $parts[0] || 0 === $parts[0]          // 127.0.0.0/8 (loopback), 10.0.0.0/8 (private), 0.0.0.0/8 (this network).
     575                                || ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )     // 172.16.0.0/12 (private).
     576                                || ( 192 === $parts[0] && 168 === $parts[1] )                      // 192.168.0.0/16 (private).
     577                                || ( 192 === $parts[0] && 0 === $parts[1] && 0 === $parts[2] )     // 192.0.0.0/24 (IETF protocol assignments).
     578                                || ( 192 === $parts[0] && 0 === $parts[1] && 2 === $parts[2] )     // 192.0.2.0/24 (TEST-NET-1).
     579                                || ( 192 === $parts[0] && 88 === $parts[1] && 99 === $parts[2] )   // 192.88.99.0/24 (6to4 relay anycast).
     580                                || ( 198 === $parts[0] && 51 === $parts[1] && 100 === $parts[2] )  // 198.51.100.0/24 (TEST-NET-2).
     581                                || ( 203 === $parts[0] && 0 === $parts[1] && 113 === $parts[2] )   // 203.0.113.0/24 (TEST-NET-3).
     582                                || ( 169 === $parts[0] && 254 === $parts[1] )                      // 169.254.0.0/16 (link-local and cloud metadata).
     583                                || ( 100 === $parts[0] && 64 <= $parts[1] && 127 >= $parts[1] )    // 100.64.0.0/10 (CGNAT).
     584                                || ( 198 === $parts[0] && 18 <= $parts[1] && 19 >= $parts[1] )     // 198.18.0.0/15 (benchmarking).
     585                                || ( 224 <= $parts[0] && 239 >= $parts[0] )                        // 224.0.0.0/4 (multicast).
     586                                || 240 <= $parts[0]                                                // 240.0.0.0/4 (reserved, includes 255.255.255.255 broadcast).
    566587                        ) {
    567588                                // If host appears local, reject unless specifically allowed.
  • branches/5.2/src/wp-includes/kses.php

    r62001 r63110  
    22162216
    22172217                // Remove any CSS containing containing \ ( & } = or comments, except for url() useage checked above.
    2218                 if ( $found && ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ) ) {
     2218                if ( $found && 0 === preg_match( '%[\\\(&=}]|/\*%', $css_test_string ) ) {
    22192219                        if ( $css != '' ) {
    22202220                                $css .= ';';
  • branches/5.2/src/wp-includes/user.php

    r47645 r63110  
    177177                                /* translators: %s: user name */
    178178                                __( '<strong>ERROR</strong>: The password you entered for the username %s is incorrect.' ),
    179                                 '<strong>' . $username . '</strong>'
     179                                '<strong>' . esc_html( $username ) . '</strong>'
    180180                        ) .
    181181                        ' <a href="' . wp_lostpassword_url() . '">' .
     
    251251                                /* translators: %s: email address */
    252252                                __( '<strong>ERROR</strong>: The password you entered for the email address %s is incorrect.' ),
    253                                 '<strong>' . $email . '</strong>'
     253                                '<strong>' . esc_html( $email ) . '</strong>'
    254254                        ) .
    255255                        ' <a href="' . wp_lostpassword_url() . '">' .
     
    24992499        $user_id   = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
    25002500        if ( ! $user_id || is_wp_error( $user_id ) ) {
    2501                 $errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn&#8217;t register you&hellip; please contact the <a href="mailto:%s">webmaster</a> !' ), get_option( 'admin_email' ) ) );
     2501                $errors->add( 'registerfail', sprintf( __( '<strong>ERROR</strong>: Couldn&#8217;t register you&hellip; please contact the <a href="mailto:%s">webmaster</a> !' ), esc_attr( get_option( 'admin_email' ) ) ) );
    25022502                return $errors;
    25032503        }
     
    27122712 * @since 3.0.0
    27132713 * @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific.
     2714 * @since 7.0.3 Added the `$user_id` parameter, which is sent with the `personal_options_update` action.
     2715 *
     2716 * @param int $user_id Optional. The ID of the user whose email is being changed. Defaults to `$_POST['user_id']` if set, otherwise 0.
    27142717 *
    27152718 * @global WP_Error $errors WP_Error object.
    27162719 */
    2717 function send_confirmation_on_profile_email() {
     2720function send_confirmation_on_profile_email( $user_id = 0 ) {
    27182721        global $errors;
     2722
     2723        // Maintain backward compatibility for those relying on a check based on $_POST['user_id'].
     2724        if ( ! $user_id && isset( $_POST['user_id'] ) ) {
     2725                $user_id = (int) $_POST['user_id'];
     2726        }
    27192727
    27202728        $current_user = wp_get_current_user();
     
    27232731        }
    27242732
    2725         if ( $current_user->ID != $_POST['user_id'] ) {
     2733        if ( 0 === $current_user->ID || $current_user->ID !== (int) $user_id ) {
    27262734                return false;
    27272735        }
     
    27372745                        );
    27382746
     2747                        $_POST['email'] = addslashes( $current_user->user_email );
    27392748                        return;
    27402749                }
     
    27502759                        delete_user_meta( $current_user->ID, '_new_email' );
    27512760
     2761                        $_POST['email'] = addslashes( $current_user->user_email );
    27522762                        return;
    27532763                }
  • branches/5.2/src/wp-signup.php

    r44626 r63110  
    954954                        break;
    955955                case 'gimmeanotherblog':
    956                         validate_another_blog_signup();
     956                        if ( 'all' === $active_signup || 'blog' === $active_signup ) {
     957                                validate_another_blog_signup();
     958                        } else {
     959                                _e( 'Site registration has been disabled.' );
     960                        }
    957961                        break;
    958962                case 'default':
Note: See TracChangeset for help on using the changeset viewer.