From d3277953b0b99c550d5de5257ddad4903f0083f6 Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 30 Jul 2026 15:50:32 +1000 Subject: [PATCH 1/2] REST API: Check for a missing post before the comment status capability. `WP_REST_Comments_Controller::create_item_permissions_check()` checked whether the user is allowed to set `status` before checking that a `post` was supplied at all. A request carrying a status but no post was therefore rejected as `rest_comment_invalid_status`, which points at the wrong parameter. Move the missing-post guard above the status capability check so the missing post is reported as such. Fixes #65761. --- .../class-wp-rest-comments-controller.php | 16 ++++++------ .../rest-api/rest-comments-controller.php | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index d14aefb1f6308..28fa689b8d020 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -568,6 +568,14 @@ public function create_item_permissions_check( $request ) { ); } + if ( empty( $request['post'] ) ) { + return new WP_Error( + 'rest_comment_invalid_post_id', + __( 'Sorry, you are not allowed to create this comment without a post.' ), + array( 'status' => 403 ) + ); + } + $edit_cap = $is_note ? array( 'edit_post', (int) $request['post'] ) : array( 'moderate_comments' ); if ( isset( $request['status'] ) && ! current_user_can( ...$edit_cap ) ) { return new WP_Error( @@ -578,14 +586,6 @@ public function create_item_permissions_check( $request ) { ); } - if ( empty( $request['post'] ) ) { - return new WP_Error( - 'rest_comment_invalid_post_id', - __( 'Sorry, you are not allowed to create this comment without a post.' ), - array( 'status' => 403 ) - ); - } - $post = get_post( (int) $request['post'] ); if ( ! $post ) { diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 8542bcd42af24..e9d1c7b2b1e5f 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -2024,6 +2024,31 @@ public function test_create_comment_no_post_id_no_permission() { $this->assertErrorResponse( 'rest_comment_invalid_post_id', $response, 403 ); } + /** + * A missing post should be reported as a missing post, even when the request + * also sets `status` and the user is not allowed to set it. + * + * @ticket 65761 + */ + public function test_create_comment_status_and_no_post_id_no_permission() { + wp_set_current_user( self::$author_id ); + + $params = array( + 'author_name' => 'Homer Jay Simpson', + 'author_email' => 'chunkylover53@aol.com', + 'author_url' => 'http://compuglobalhypermeganet.com', + 'content' => 'Here\’s to alcohol: the cause of, and solution to, all of life\’s problems.', + 'status' => 'approved', + ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( wp_json_encode( $params ) ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_post_id', $response, 403 ); + } + public function test_create_comment_invalid_post_id() { wp_set_current_user( self::$admin_id ); From d2e72efc3ede5eaea76a0a3b370889e40be607e3 Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 30 Jul 2026 16:15:58 +1000 Subject: [PATCH 2/2] REST API: Add note coverage for a comment status set without a post. Notes resolve the status capability against `edit_post` with the submitted post ID. With no post that becomes `current_user_can( 'edit_post', 0 )`, which `map_meta_cap()` denies for every role, so the missing post was reported as a status error for all callers including administrators. Cover the note variant so the guard order stays put. See #65761. --- .../rest-api/rest-comments-controller.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index e9d1c7b2b1e5f..814ed5da91039 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -3838,6 +3838,36 @@ public function test_create_note_status() { $this->assertSame( 'note', $new_comment->comment_type ); } + /** + * A missing post should be reported as a missing post for notes too. + * + * Without a post, the `status` capability check falls back to + * `current_user_can( 'edit_post', 0 )`, which no role can satisfy. An + * administrator is used here to show the missing post is reported even for a + * user holding every capability. + * + * @ticket 65761 + */ + public function test_create_note_status_and_no_post_id() { + wp_set_current_user( self::$admin_id ); + + $params = array( + 'author_name' => 'Ishmael', + 'author_email' => 'herman-melville@earthlink.net', + 'author_url' => 'https://en.wikipedia.org/wiki/Herman_Melville', + 'content' => 'Comic Book Guy', + 'type' => 'note', + 'status' => 'hold', + ); + + $request = new WP_REST_Request( 'POST', '/wp/v2/comments' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( wp_json_encode( $params ) ); + + $response = rest_get_server()->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_post_id', $response, 403 ); + } + /** * @ticket 64096 */