@@ -1801,6 +1801,132 @@ public function test_collaboration_deprecated_sync_route() {
18011801 $ this ->assertContains ( 'c3luYyByb3V0ZQ== ' , $ update_data );
18021802 }
18031803
1804+ /*
1805+ * Payload limit and permission hardening tests.
1806+ */
1807+
1808+ /**
1809+ * Verifies that a request body exceeding MAX_BODY_SIZE returns a 413 error.
1810+ *
1811+ * @ticket 64696
1812+ */
1813+ public function test_collaboration_oversized_body_rejected (): void {
1814+ wp_set_current_user ( self ::$ editor_id );
1815+
1816+ $ request = new WP_REST_Request ( 'POST ' , '/wp-collaboration/v1/updates ' );
1817+ // Set a body larger than MAX_BODY_SIZE (16 MB).
1818+ $ request ->set_body ( str_repeat ( 'x ' , 16 * MB_IN_BYTES + 1 ) );
1819+ $ request ->set_body_params (
1820+ array (
1821+ 'rooms ' => array (
1822+ $ this ->build_room ( $ this ->get_post_room () ),
1823+ ),
1824+ )
1825+ );
1826+
1827+ $ server = new WP_HTTP_Polling_Collaboration_Server (
1828+ new WP_Collaboration_Table_Storage ()
1829+ );
1830+
1831+ $ result = $ server ->validate_request ( $ request );
1832+
1833+ $ this ->assertWPError ( $ result );
1834+ $ this ->assertSame ( 'rest_collaboration_body_too_large ' , $ result ->get_error_code () );
1835+ $ this ->assertSame ( 413 , $ result ->get_error_data ()['status ' ] );
1836+ }
1837+
1838+ /**
1839+ * Verifies that more than MAX_ROOMS_PER_REQUEST rooms is rejected by schema validation.
1840+ *
1841+ * @ticket 64696
1842+ */
1843+ public function test_collaboration_too_many_rooms_rejected (): void {
1844+ wp_set_current_user ( self ::$ editor_id );
1845+
1846+ $ rooms = array ();
1847+ for ( $ i = 0 ; $ i <= WP_HTTP_Polling_Collaboration_Server::MAX_ROOMS_PER_REQUEST ; $ i ++ ) {
1848+ $ post_id = self ::factory ()->post ->create ( array ( 'post_author ' => self ::$ editor_id ) );
1849+ $ rooms [] = $ this ->build_room ( 'postType/post: ' . $ post_id , (string ) $ i );
1850+ }
1851+
1852+ $ response = $ this ->dispatch_collaboration ( $ rooms );
1853+
1854+ $ this ->assertSame ( 400 , $ response ->get_status (), 'Exceeding MAX_ROOMS_PER_REQUEST should return 400. ' );
1855+ }
1856+
1857+ /**
1858+ * Verifies that a non-numeric object ID in a room name is rejected.
1859+ *
1860+ * @ticket 64696
1861+ */
1862+ public function test_collaboration_non_numeric_object_id_rejected (): void {
1863+ wp_set_current_user ( self ::$ editor_id );
1864+
1865+ $ response = $ this ->dispatch_collaboration (
1866+ array (
1867+ $ this ->build_room ( 'postType/post:abc ' ),
1868+ )
1869+ );
1870+
1871+ $ this ->assertErrorResponse ( 'rest_cannot_edit ' , $ response , 403 );
1872+ }
1873+
1874+ /**
1875+ * Verifies that a post type mismatch (room says page but post is a post) is rejected.
1876+ *
1877+ * @ticket 64696
1878+ */
1879+ public function test_collaboration_post_type_mismatch_rejected (): void {
1880+ wp_set_current_user ( self ::$ editor_id );
1881+
1882+ // self::$post_id is a 'post', but the room claims 'page'.
1883+ $ response = $ this ->dispatch_collaboration (
1884+ array (
1885+ $ this ->build_room ( 'postType/page: ' . self ::$ post_id ),
1886+ )
1887+ );
1888+
1889+ $ this ->assertErrorResponse ( 'rest_cannot_edit ' , $ response , 403 );
1890+ }
1891+
1892+ /**
1893+ * Verifies that a taxonomy term that doesn't exist is rejected.
1894+ *
1895+ * @ticket 64696
1896+ */
1897+ public function test_collaboration_nonexistent_taxonomy_term_rejected (): void {
1898+ wp_set_current_user ( self ::$ editor_id );
1899+
1900+ $ response = $ this ->dispatch_collaboration (
1901+ array (
1902+ $ this ->build_room ( 'taxonomy/category:999999 ' ),
1903+ )
1904+ );
1905+
1906+ $ this ->assertErrorResponse ( 'rest_cannot_edit ' , $ response , 403 );
1907+ }
1908+
1909+ /**
1910+ * Verifies that a taxonomy term in the wrong taxonomy is rejected.
1911+ *
1912+ * @ticket 64696
1913+ */
1914+ public function test_collaboration_taxonomy_term_wrong_taxonomy_rejected (): void {
1915+ wp_set_current_user ( self ::$ editor_id );
1916+
1917+ // Create a term in 'category' taxonomy.
1918+ $ term = self ::factory ()->term ->create ( array ( 'taxonomy ' => 'category ' ) );
1919+
1920+ // Try to access it as a 'post_tag' term.
1921+ $ response = $ this ->dispatch_collaboration (
1922+ array (
1923+ $ this ->build_room ( 'taxonomy/post_tag: ' . $ term ),
1924+ )
1925+ );
1926+
1927+ $ this ->assertErrorResponse ( 'rest_cannot_edit ' , $ response , 403 );
1928+ }
1929+
18041930 /**
18051931 * An idle poll (no new updates) should use at most 4 queries per room:
18061932 * 1. SELECT … FROM collaboration WHERE type = 'awareness' (read + ownership check)
0 commit comments