From cddef1f2e2e7ebe61abb80e0a28067bdc4984238 Mon Sep 17 00:00:00 2001 From: chriszarate Date: Mon, 2 Mar 2026 17:08:25 -0700 Subject: [PATCH] Check wp_user_id before accepting awareness update --- .../class-wp-http-polling-sync-server.php | 20 +++++++++++++-- .../tests/rest-api/rest-sync-server.php | 25 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/collaboration/class-wp-http-polling-sync-server.php b/src/wp-includes/collaboration/class-wp-http-polling-sync-server.php index bc9d208f096be..2045a2acea4eb 100644 --- a/src/wp-includes/collaboration/class-wp-http-polling-sync-server.php +++ b/src/wp-includes/collaboration/class-wp-http-polling-sync-server.php @@ -181,10 +181,25 @@ public function check_permissions( WP_REST_Request $request ) { ); } - $rooms = $request['rooms']; + $rooms = $request['rooms']; + $wp_user_id = get_current_user_id(); foreach ( $rooms as $room ) { - $room = $room['room']; + $client_id = $room['client_id']; + $room = $room['room']; + + // Check that the client_id is not already owned by another user. + $existing_awareness = $this->storage->get_awareness_state( $room ); + foreach ( $existing_awareness as $entry ) { + if ( $client_id === $entry['client_id'] && $wp_user_id !== $entry['wp_user_id'] ) { + return new WP_Error( + 'rest_cannot_edit', + __( 'Client ID is already in use by another user.' ), + array( 'status' => rest_authorization_required_code() ) + ); + } + } + $type_parts = explode( '/', $room, 2 ); $object_parts = explode( ':', $type_parts[1] ?? '', 2 ); @@ -341,6 +356,7 @@ private function process_awareness_update( string $room, int $client_id, ?array 'client_id' => $client_id, 'state' => $awareness_update, 'updated_at' => $current_time, + 'wp_user_id' => get_current_user_id(), ); } diff --git a/tests/phpunit/tests/rest-api/rest-sync-server.php b/tests/phpunit/tests/rest-api/rest-sync-server.php index 0180f02ca3b45..b512193a9a9f2 100644 --- a/tests/phpunit/tests/rest-api/rest-sync-server.php +++ b/tests/phpunit/tests/rest-api/rest-sync-server.php @@ -697,6 +697,31 @@ public function test_sync_awareness_updates_existing_client() { $this->assertSame( array( 'cursor' => 'updated' ), $awareness[1] ); } + public function test_sync_awareness_client_id_cannot_be_used_by_another_user() { + wp_set_current_user( self::$editor_id ); + + $room = $this->get_post_room(); + + // Editor establishes awareness with client_id 1. + $this->dispatch_sync( + array( + $this->build_room( $room, 1, 0, array( 'name' => 'Editor' ) ), + ) + ); + + // A different user tries to use the same client_id. + $editor_id_2 = self::factory()->user->create( array( 'role' => 'editor' ) ); + wp_set_current_user( $editor_id_2 ); + + $response = $this->dispatch_sync( + array( + $this->build_room( $room, 1, 0, array( 'name' => 'Impostor' ) ), + ) + ); + + $this->assertErrorResponse( 'rest_cannot_edit', $response, 403 ); + } + /* * Multiple rooms tests. */