Make WordPress Core

Changeset 63111


Ignore:
Timestamp:
08/06/2026 07:53:19 PM (5 weeks ago)
Author:
desrosj
Message:

Security: Backport the WordPress 7.0.3 security fixes to the 5.1 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.1 branch.

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

Location:
branches/5.1/src
Files:
7 edited

Legend:

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

    r43577 r63111  
    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.1/src/wp-admin/includes/user.php

    r44708 r63111  
    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.1/src/wp-includes/canonical.php

    r43571 r63111  
    662662
    663663        if ( get_query_var( 'name' ) ) {
     664                $publicly_viewable_post_types = array_filter( get_post_types( array( 'exclude_from_search' => false ) ), 'is_post_type_viewable' );
     665
    664666                $where = $wpdb->prepare( 'post_name LIKE %s', $wpdb->esc_like( get_query_var( 'name' ) ) . '%' );
    665667
    666668                // if any of post_type, year, monthnum, or day are set, use them to refine the query
    667669                if ( get_query_var( 'post_type' ) ) {
    668                         $where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
     670                        if ( is_array( get_query_var( 'post_type' ) ) ) {
     671                                $post_types = array_intersect( get_query_var( 'post_type' ), $publicly_viewable_post_types );
     672                                if ( empty( $post_types ) ) {
     673                                        return false;
     674                                }
     675                                $where .= " AND post_type IN ('" . implode( "', '", esc_sql( $post_types ) ) . "')";
     676                        } else {
     677                                if ( ! in_array( get_query_var( 'post_type' ), $publicly_viewable_post_types, true ) ) {
     678                                        return false;
     679                                }
     680                                $where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
     681                        }
    669682                } else {
    670                         $where .= " AND post_type IN ('" . implode( "', '", get_post_types( array( 'public' => true ) ) ) . "')";
     683                        $where .= " AND post_type IN ('" . implode( "', '", esc_sql( $publicly_viewable_post_types ) ) . "')";
    671684                }
    672685
  • branches/5.1/src/wp-includes/http.php

    r46490 r63111  
    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.1/src/wp-includes/kses.php

    r62002 r63111  
    22132213
    22142214                // Remove any CSS containing containing \ ( & } = or comments, except for url() useage checked above.
    2215                 if ( $found && ! preg_match( '%[\\\(&=}]|/\*%', $css_test_string ) ) {
     2215                if ( $found && 0 === preg_match( '%[\\\(&=}]|/\*%', $css_test_string ) ) {
    22162216                        if ( $css != '' ) {
    22172217                                $css .= ';';
  • branches/5.1/src/wp-includes/user.php

    r47646 r63111  
    181181                                /* translators: %s: user name */
    182182                                __( '<strong>ERROR</strong>: The password you entered for the username %s is incorrect.' ),
    183                                 '<strong>' . $username . '</strong>'
     183                                '<strong>' . esc_html( $username ) . '</strong>'
    184184                        ) .
    185185                        ' <a href="' . wp_lostpassword_url() . '">' .
     
    255255                                /* translators: %s: email address */
    256256                                __( '<strong>ERROR</strong>: The password you entered for the email address %s is incorrect.' ),
    257                                 '<strong>' . $email . '</strong>'
     257                                '<strong>' . esc_html( $email ) . '</strong>'
    258258                        ) .
    259259                        ' <a href="' . wp_lostpassword_url() . '">' .
     
    25032503        $user_id   = wp_create_user( $sanitized_user_login, $user_pass, $user_email );
    25042504        if ( ! $user_id || is_wp_error( $user_id ) ) {
    2505                 $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' ) ) );
     2505                $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' ) ) ) );
    25062506                return $errors;
    25072507        }
     
    27162716 * @since 3.0.0
    27172717 * @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific.
     2718 * @since 7.0.3 Added the `$user_id` parameter, which is sent with the `personal_options_update` action.
     2719 *
     2720 * @param int $user_id Optional. The ID of the user whose email is being changed. Defaults to `$_POST['user_id']` if set, otherwise 0.
    27182721 *
    27192722 * @global WP_Error $errors WP_Error object.
    27202723 */
    2721 function send_confirmation_on_profile_email() {
     2724function send_confirmation_on_profile_email( $user_id = 0 ) {
    27222725        global $errors;
     2726
     2727        // Maintain backward compatibility for those relying on a check based on $_POST['user_id'].
     2728        if ( ! $user_id && isset( $_POST['user_id'] ) ) {
     2729                $user_id = (int) $_POST['user_id'];
     2730        }
    27232731
    27242732        $current_user = wp_get_current_user();
     
    27272735        }
    27282736
    2729         if ( $current_user->ID != $_POST['user_id'] ) {
     2737        if ( 0 === $current_user->ID || $current_user->ID !== (int) $user_id ) {
    27302738                return false;
    27312739        }
     
    27412749                        );
    27422750
     2751                        $_POST['email'] = addslashes( $current_user->user_email );
    27432752                        return;
    27442753                }
     
    27542763                        delete_user_meta( $current_user->ID, '_new_email' );
    27552764
     2765                        $_POST['email'] = addslashes( $current_user->user_email );
    27562766                        return;
    27572767                }
  • branches/5.1/src/wp-signup.php

    r44626 r63111  
    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.