Make WordPress Core


Ignore:
Timestamp:
11/21/2025 05:37:23 PM (9 months ago)
Author:
adamsilverstein
Message:

Comments: ensure unauthenticated users cannot access the single comment endpoint for notes.

Fix an issue where notes could be accessed by unauthenticated users by using the single comment REST API endpoint and passing the comment ID (/wp/v2/comments/<ID>). This fix only affects the note type.

Props adamsilverstein, peterwilsoncc, westonruter.
See #44157.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-comments-controller.php

    r61105 r61276  
    41344134                $this->assertStringContainsString( 'type=note', $children[0]['href'] );
    41354135        }
     4136
     4137        /**
     4138         * Test retrieving comments by type as authenticated user.
     4139         *
     4140         * @dataProvider data_comment_type_provider
     4141         * @ticket 44157
     4142         *
     4143         * @param string $comment_type The comment type to test.
     4144         * @param int    $count        The number of comments to create.
     4145         */
     4146        public function test_get_items_type_arg_authenticated( $comment_type, $count ) {
     4147                wp_set_current_user( self::$admin_id );
     4148
     4149                $args = array(
     4150                        'comment_approved' => 1,
     4151                        'comment_post_ID'  => self::$post_id,
     4152                        'user_id'          => self::$author_id,
     4153                        'comment_type'     => $comment_type,
     4154                );
     4155
     4156                // Create comments of the specified type.
     4157                for ( $i = 0; $i < $count; $i++ ) {
     4158                        self::factory()->comment->create( $args );
     4159                }
     4160
     4161                $request = new WP_REST_Request( 'GET', '/wp/v2/comments' );
     4162                $request->set_param( 'type', $comment_type );
     4163                $request->set_param( 'per_page', self::$per_page );
     4164
     4165                $response = rest_get_server()->dispatch( $request );
     4166                $this->assertSame( 200, $response->get_status(), 'Comments endpoint is expected to return a 200 status' );
     4167
     4168                $comments       = $response->get_data();
     4169                $expected_count = 'comment' === $comment_type ? $count + self::$total_comments : $count;
     4170                $this->assertCount( $expected_count, $comments, "comment type '{$comment_type}' is expect to have {$expected_count} comments" );
     4171
     4172                // Next, test getting the individual comments.
     4173                foreach ( $comments as $comment ) {
     4174                        $request  = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d', $comment['id'] ) );
     4175                        $response = rest_get_server()->dispatch( $request );
     4176
     4177                        $this->assertSame( 200, $response->get_status(), 'Individual comment endpoint is expected to return a 200 status' );
     4178                        $data = $response->get_data();
     4179                        $this->assertSame( $comment_type, $data['type'], "Individual comment is expected to have type '{$comment_type}'" );
     4180                }
     4181        }
     4182
     4183        /**
     4184         * Test retrieving comments by type as unauthenticated user.
     4185         *
     4186         * @dataProvider data_comment_type_provider
     4187         * @ticket 44157
     4188         *
     4189         * @param string $comment_type The comment type to test.
     4190         * @param int    $count        The number of comments to create.
     4191         */
     4192        public function test_get_items_type_arg_unauthenticated( $comment_type, $count ) {
     4193                // First, create comments as admin.
     4194                wp_set_current_user( self::$admin_id );
     4195
     4196                $args = array(
     4197                        'comment_approved' => 1,
     4198                        'comment_post_ID'  => self::$post_id,
     4199                        'user_id'          => self::$author_id,
     4200                        'comment_type'     => $comment_type,
     4201                );
     4202
     4203                $comments = array();
     4204
     4205                for ( $i = 0; $i < $count; $i++ ) {
     4206                        $comments[] = self::factory()->comment->create( $args );
     4207                }
     4208
     4209                // Log out and test as unauthenticated user.
     4210                wp_logout();
     4211
     4212                $request = new WP_REST_Request( 'GET', '/wp/v2/comments' );
     4213                $request->set_param( 'type', $comment_type );
     4214                $request->set_param( 'per_page', self::$per_page );
     4215
     4216                $response = rest_get_server()->dispatch( $request );
     4217
     4218                // Only comments can be retrieved from the /comments (multiple) endpoint when unauthenticated.
     4219                $expected_status = 'comment' === $comment_type ? 200 : 401;
     4220                $this->assertSame( $expected_status, $response->get_status(), 'Comments endpoint did not return the expected status' );
     4221                if ( 'comment' !== $comment_type ) {
     4222                        $this->assertErrorResponse( 'rest_forbidden_param', $response, 401, 'Comments endpoint did not return the expected error response for forbidden parameters' );
     4223                }
     4224
     4225                // Individual comments.
     4226                foreach ( $comments as $comment ) {
     4227                        $request  = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d', $comment ) );
     4228                        $response = rest_get_server()->dispatch( $request );
     4229
     4230                        // Individual comments using the /comments/<id> endpoint can be retrieved by
     4231                        // unauthenticated users - except for the 'note' type which is restricted.
     4232                        // See https://core.trac.wordpress.org/ticket/44157.
     4233                        $this->assertSame( 'note' === $comment_type ? 401 : 200, $response->get_status(), 'Individual comment endpoint did not return the expected status' );
     4234                }
     4235        }
     4236
     4237        /**
     4238         * Data provider for comment type tests.
     4239         *
     4240         * @return array[] Data provider.
     4241         */
     4242        public function data_comment_type_provider() {
     4243                return array(
     4244                        'comment type'    => array( 'comment', 5 ),
     4245                        'annotation type' => array( 'annotation', 5 ),
     4246                        'discussion type' => array( 'discussion', 9 ),
     4247                        'note type'       => array( 'note', 3 ),
     4248                );
     4249        }
    41364250}
Note: See TracChangeset for help on using the changeset viewer.