Make WordPress Core

Changeset 64179


Ignore:
Timestamp:
10/06/2026 05:43:00 PM (3 days ago)
Author:
johnbillion
Message:

Security: Backport the WordPress 7.1.3 security fixes to the 5.1 branch.

  • REST API: Require both capabilities to change a post's sticky status.
  • Query: Prevent exposure of comments on unviewable posts.
  • Posts, Post Types: Fire dynamic status transition hooks only for registered statuses and post types.
  • Administration: Treat contextual help tab links as selectors.
  • Embeds: Remove support for Imgur oEmbeds.
  • HTTP: Improve relative path resolution in WP_Http::make_absolute_url().

Merges r64127, r64128, r64130, r64131, r64132, r64133 to the 5.1 branch.

Props xknown, jeremyfelt, jorbin, peterwilsoncc, ehtis, westonruter, lancewillett, jonsurrell, marcs0h, rfaile313, johnbillion, vortfu.

Location:
branches/5.1
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/5.1

  • branches/5.1/src/js/_enqueues/admin/common.js

    r44722 r64179  
    339339        link.parent('li').addClass('active');
    340340
    341         panel = $( link.attr('href') );
     341        panel = $( document ).find( link.attr('href') );
    342342
    343343        // Panels
  • branches/5.1/src/wp-includes/class-http.php

    r44397 r64179  
    963963                        // Strip all /path/../ out of the path.
    964964                        while ( strpos( $path, '../' ) > 1 ) {
    965                                 $path = preg_replace( '![^/]+/\.\./!', '', $path );
     965                                $path = preg_replace( '![^/]+/\.\./!', '', $path, -1, $segment_replacement_count );
     966                                if ( 0 === $segment_replacement_count ) {
     967                                        break;
     968                                }
    966969                        }
    967970
  • branches/5.1/src/wp-includes/class-oembed.php

    r44552 r64179  
    7676                        '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i' => array( 'https://api.instagram.com/oembed', true ),
    7777                        '#https?://(open|play)\.spotify\.com/.*#i'     => array( 'https://embed.spotify.com/oembed/', true ),
    78                         '#https?://(.+\.)?imgur\.com/.*#i'             => array( 'https://api.imgur.com/oembed', true ),
    7978                        '#https?://(www\.)?meetu(\.ps|p\.com)/.*#i'    => array( 'https://api.meetup.com/oembed', true ),
    8079                        '#https?://(www\.)?issuu\.com/.+/docs/.+#i'    => array( 'https://issuu.com/oembed_wp', true ),
    … …  
    160159                 * | Flickr       | flic.kr                                   |      Yes       | 3.6.0   |
    161160                 * | Spotify      | spotify.com                               |      Yes       | 3.6.0   |
    162                  * | Imgur        | imgur.com                                 |      Yes       | 3.9.0   |
    163161                 * | Meetup.com   | meetup.com                                |      Yes       | 3.9.0   |
    164162                 * | Meetup.com   | meetu.ps                                  |      Yes       | 3.9.0   |
    … …  
    212210                 * | Photobucket  | photobucket.com      |      No        | 2.9.0     | 5.1.0     |
    213211                 * | Funny or Die | funnyordie.com       |      Yes       | 3.0.0     | 5.1.0     |
     212                 * | Imgur        | imgur.com            |      Yes       | 3.9.0     | 7.1.3     |
    214213                 *
    215214                 * @see wp_oembed_add_provider()
  • branches/5.1/src/wp-includes/class-wp-query.php

    r54570 r64179  
    30203020                }
    30213021
    3022                 if ( ! empty( $this->posts ) && $this->is_comment_feed && $this->is_singular ) {
    3023                         /** This filter is documented in wp-includes/query.php */
    3024                         $cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
    3025 
    3026                         /** This filter is documented in wp-includes/query.php */
    3027                         $cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
    3028 
    3029                         /** This filter is documented in wp-includes/query.php */
    3030                         $cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) );
    3031                         $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
    3032 
    3033                         /** This filter is documented in wp-includes/query.php */
    3034                         $corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
    3035                         $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
    3036 
    3037                         /** This filter is documented in wp-includes/query.php */
    3038                         $climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
    3039 
    3040                         $comments_request = "SELECT {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
    3041                         $comments         = $wpdb->get_results( $comments_request );
    3042                         // Convert to WP_Comment
    3043                         $this->comments      = array_map( 'get_comment', $comments );
    3044                         $this->comment_count = count( $this->comments );
    3045                 }
    3046 
    30473022                // Check post status to determine if post should be displayed.
    30483023                if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) {
    … …  
    30953070                }
    30963071
     3072                if ( ! empty( $this->posts ) && $this->is_comment_feed && $this->is_singular ) {
     3073                        /** This filter is documented in wp-includes/query.php */
     3074                        $cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
     3075
     3076                        /** This filter is documented in wp-includes/query.php */
     3077                        $cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
     3078
     3079                        /** This filter is documented in wp-includes/query.php */
     3080                        $cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) );
     3081                        $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
     3082
     3083                        /** This filter is documented in wp-includes/query.php */
     3084                        $corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
     3085                        $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
     3086
     3087                        /** This filter is documented in wp-includes/query.php */
     3088                        $climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
     3089
     3090                        $comments_request = "SELECT {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
     3091                        $comments         = $wpdb->get_results( $comments_request );
     3092                        // Convert to WP_Comment
     3093                        $this->comments      = array_map( 'get_comment', $comments );
     3094                        $this->comment_count = count( $this->comments );
     3095                }
     3096
    30973097                // Put sticky posts at the top of the posts array
    30983098                $sticky_posts = get_option( 'sticky_posts' );
  • branches/5.1/src/wp-includes/post.php

    r54570 r64179  
    45494549        do_action( 'transition_post_status', $new_status, $old_status, $post );
    45504550
    4551         /**
    4552          * Fires when a post is transitioned from one status to another.
    4553          *
    4554          * The dynamic portions of the hook name, `$new_status` and `$old status`,
    4555          * refer to the old and new post statuses, respectively.
    4556          *
    4557          * @since 2.3.0
    4558          *
    4559          * @param WP_Post $post Post object.
    4560          */
    4561         do_action( "{$old_status}_to_{$new_status}", $post );
    4562 
    4563         /**
    4564          * Fires when a post is transitioned from one status to another.
    4565          *
    4566          * The dynamic portions of the hook name, `$new_status` and `$post->post_type`,
    4567          * refer to the new post status and post type, respectively.
    4568          *
    4569          * Please note: When this action is hooked using a particular post status (like
    4570          * 'publish', as `publish_{$post->post_type}`), it will fire both when a post is
    4571          * first transitioned to that status from something else, as well as upon
    4572          * subsequent post updates (old and new status are both the same).
    4573          *
    4574          * Therefore, if you are looking to only fire a callback when a post is first
    4575          * transitioned to a status, use the {@see 'transition_post_status'} hook instead.
    4576          *
    4577          * @since 2.3.0
    4578          *
    4579          * @param int     $post_id Post ID.
    4580          * @param WP_Post $post    Post object.
    4581          */
    4582         do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );
     4551        $new_status_object = get_post_status_object( $new_status );
     4552        $old_status_valid  = get_post_status_object( $old_status ) || 'new' === $old_status;
     4553        $post_type_object  = get_post_type_object( $post->post_type );
     4554
     4555        if ( $new_status_object && $old_status_valid ) {
     4556                /**
     4557                 * Fires when a post is transitioned from one status to another.
     4558                 *
     4559                 * The dynamic portions of the hook name, `$new_status` and `$old status`,
     4560                 * refer to the old and new post statuses, respectively.
     4561                 *
     4562                 * @since 2.3.0
     4563                 *
     4564                 * @param WP_Post $post Post object.
     4565                 */
     4566                do_action( "{$old_status}_to_{$new_status}", $post );
     4567        }
     4568
     4569        if ( $new_status_object && $post_type_object ) {
     4570                /**
     4571                 * Fires when a post is transitioned from one status to another.
     4572                 *
     4573                 * The dynamic portions of the hook name, `$new_status` and `$post->post_type`,
     4574                 * refer to the new post status and post type, respectively.
     4575                 *
     4576                 * Please note: When this action is hooked using a particular post status (like
     4577                 * 'publish', as `publish_{$post->post_type}`), it will fire both when a post is
     4578                 * first transitioned to that status from something else, as well as upon
     4579                 * subsequent post updates (old and new status are both the same).
     4580                 *
     4581                 * Therefore, if you are looking to only fire a callback when a post is first
     4582                 * transitioned to a status, use the {@see 'transition_post_status'} hook instead.
     4583                 *
     4584                 * @since 2.3.0
     4585                 *
     4586                 * @param int     $post_id Post ID.
     4587                 * @param WP_Post $post    Post object.
     4588                 */
     4589                do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );
     4590        }
    45834591}
    45844592
  • branches/5.1/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r60835 r64179  
    552552                }
    553553
    554                 if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
     554                if ( ! empty( $request['sticky'] ) && ( ! current_user_can( $post_type->cap->edit_others_posts ) || ! current_user_can( $post_type->cap->publish_posts ) ) ) {
    555555                        return new WP_Error( 'rest_cannot_assign_sticky', __( 'Sorry, you are not allowed to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) );
    556556                }
    … …  
    707707                }
    708708
    709                 if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) && ! current_user_can( $post_type->cap->publish_posts ) ) {
     709                if ( isset( $request['sticky'] ) && is_sticky( $post->ID ) !== (bool) $request['sticky'] && ( ! current_user_can( $post_type->cap->edit_others_posts ) || ! current_user_can( $post_type->cap->publish_posts ) ) ) {
    710710                        return new WP_Error( 'rest_cannot_assign_sticky', __( 'Sorry, you are not allowed to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) );
    711711                }
Note: See TracChangeset for help on using the changeset viewer.