Make WordPress Core


Ignore:
Timestamp:
09/17/2026 09:05:55 PM (6 hours ago)
Author:
desrosj
Message:

Security: Backport the WordPress 7.1.1 security fixes to the 5.4 branch.

  • Posts, Post Types: Reject a supplied post ID on the create path in _wp_translate_postdata().
  • Comments: Enforce target post permissions when updating notes via REST.
  • XML-RPC: Reject writes to internal-only builtin post types.
  • Administration: Add authorization check to wp_ajax_sample_permalink().
  • Customize: Improve header_image_data theme mod sanitization.
  • Themes: Escape the theme installer preview route value.
  • Plugins: Require network plugin authority to Ajax-activate a network-only plugin.
  • Formatting: Prevent wpautop() moving a paragraph into an attribute of a blockquote.

Merges r63657, r63658, r63659, r63660, r63665, r63669, r63672, r63675 to the 5.4 branch.

Props xknown, westonruter, jorbin, vortfu, batmoo, davidbinda, jeremyfelt, adamsilverstein, ramonopoly, villanovachile, johnbillion, peterwilsoncc, lancewillett, jonsurrell, dmsnell, whyisjake, buffer1024, joehoyle, rafiem.

Location:
branches/5.4
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/5.4

  • branches/5.4/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php

    r47391 r63708  
    769769         *
    770770         * @since 4.7.0
     771         * @since 7.1.0 Target post permissions are checked when a comment's parent post is changed.
    771772         *
    772773         * @param WP_REST_Request $request Full details about the request.
     
    785786                                array( 'status' => rest_authorization_required_code() )
    786787                        );
     788                }
     789
     790                /*
     791                 * check_edit_permission() above only establishes that the comment may be
     792                 * edited where it currently sits, because 'edit_comment' maps to 'edit_post'
     793                 * on the comment's current parent. When the parent is being changed, the new
     794                 * parent has to be authorized as well. Without this, a user holding
     795                 * edit_comment on their own comment could reparent it onto any post,
     796                 * including posts they can neither read nor edit.
     797                 */
     798                if ( isset( $request['post'] ) && (int) $request['post'] !== (int) $comment->comment_post_ID ) {
     799                        $target_check = $this->check_target_post_permission( (int) $request['post'] );
     800
     801                        if ( is_wp_error( $target_check ) ) {
     802                                return $target_check;
     803                        }
    787804                }
    788805
     
    18691886                return $email;
    18701887        }
     1888
     1889        /**
     1890         * Checks that a post can receive a comment from the current user.
     1891         *
     1892         * Used when changing the parent post of an existing comment, so that
     1893         * attaching a comment to a post is authorized the same way whichever
     1894         * path it arrives by.
     1895         *
     1896         * @since 7.1.0
     1897         *
     1898         * @param int $post_id Target post ID.
     1899         * @return true|WP_Error True if the post can receive the comment, error object otherwise.
     1900         */
     1901        protected function check_target_post_permission( $post_id ) {
     1902                if ( ! $post_id ) {
     1903                        return new WP_Error(
     1904                                'rest_comment_invalid_post_id',
     1905                                __( 'Sorry, you are not allowed to create this comment without a post.' ),
     1906                                array( 'status' => 403 )
     1907                        );
     1908                }
     1909
     1910                /*
     1911                 * A comment needs either comment moderation rights or edit access to the
     1912                 * post, which is what check_edit_permission() grants on the post a comment
     1913                 * is moving away from. Requiring the same at the destination means both
     1914                 * ends of a move are authorized alike.
     1915                 */
     1916                if ( ! current_user_can( 'moderate_comments' ) && ! current_user_can( 'edit_post', $post_id ) ) {
     1917                        return new WP_Error(
     1918                                'rest_cannot_edit',
     1919                                __( 'Sorry, you are not allowed to edit this comment.' ),
     1920                                array( 'status' => rest_authorization_required_code() )
     1921                        );
     1922                }
     1923
     1924                $post = get_post( $post_id );
     1925
     1926                if ( ! $post ) {
     1927                        return new WP_Error(
     1928                                'rest_comment_invalid_post_id',
     1929                                __( 'Sorry, you are not allowed to create this comment without a post.' ),
     1930                                array( 'status' => 403 )
     1931                        );
     1932                }
     1933
     1934                /*
     1935                 * The create-time draft and comments-open rules are deliberately not applied
     1936                 * here, because moderators move comments onto posts whose discussion has
     1937                 * closed and onto drafts today. Enforcing them would break that without
     1938                 * blocking anything the capability check above already permits.
     1939                 */
     1940                return true;
     1941        }
    18711942}
Note: See TracChangeset for help on using the changeset viewer.