Make WordPress Core

Changeset 56096


Ignore:
Timestamp:
06/28/2023 05:37:52 PM (3 years ago)
Author:
kadamwhite
Message:

REST API: Expose current $request object to cors_header filters in WP_REST_SERVER->serve_request().

Allows headers to be more easily set on a per-response basis when more or less security is needed on a specific route.

Props bor0, rachelbaker, spacedmonkey, chaion07, oglekler, SergeyBiryukov.
Fixes #57752.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/class-wp-rest-server.php

    r56031 r56096  
    322322                 */
    323323                $this->send_header( 'X-Content-Type-Options', 'nosniff' );
    324                 $expose_headers = array( 'X-WP-Total', 'X-WP-TotalPages', 'Link' );
    325 
    326                 /**
    327                  * Filters the list of response headers that are exposed to REST API CORS requests.
    328                  *
    329                  * @since 5.5.0
    330                  *
    331                  * @param string[] $expose_headers The list of response headers to expose.
    332                  */
    333                 $expose_headers = apply_filters( 'rest_exposed_cors_headers', $expose_headers );
    334 
    335                 $this->send_header( 'Access-Control-Expose-Headers', implode( ', ', $expose_headers ) );
    336 
    337                 $allow_headers = array(
    338                         'Authorization',
    339                         'X-WP-Nonce',
    340                         'Content-Disposition',
    341                         'Content-MD5',
    342                         'Content-Type',
    343                 );
    344 
    345                 /**
    346                  * Filters the list of request headers that are allowed for REST API CORS requests.
    347                  *
    348                  * The allowed headers are passed to the browser to specify which
    349                  * headers can be passed to the REST API. By default, we allow the
    350                  * Content-* headers needed to upload files to the media endpoints.
    351                  * As well as the Authorization and Nonce headers for allowing authentication.
    352                  *
    353                  * @since 5.5.0
    354                  *
    355                  * @param string[] $allow_headers The list of request headers to allow.
    356                  */
    357                 $allow_headers = apply_filters( 'rest_allowed_cors_headers', $allow_headers );
    358 
    359                 $this->send_header( 'Access-Control-Allow-Headers', implode( ', ', $allow_headers ) );
    360324
    361325                /**
     
    436400                        $request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] );
    437401                }
     402
     403                $expose_headers = array( 'X-WP-Total', 'X-WP-TotalPages', 'Link' );
     404
     405                /**
     406                 * Filters the list of response headers that are exposed to REST API CORS requests.
     407                 *
     408                 * @since 5.5.0
     409                 *
     410                 * @param string[] $expose_headers The list of response headers to expose.
     411                 * @param WP_REST_Request The request in context.
     412                 */
     413                $expose_headers = apply_filters( 'rest_exposed_cors_headers', $expose_headers, $request );
     414
     415                $this->send_header( 'Access-Control-Expose-Headers', implode( ', ', $expose_headers ) );
     416
     417                $allow_headers = array(
     418                        'Authorization',
     419                        'X-WP-Nonce',
     420                        'Content-Disposition',
     421                        'Content-MD5',
     422                        'Content-Type',
     423                );
     424
     425                /**
     426                 * Filters the list of request headers that are allowed for REST API CORS requests.
     427                 *
     428                 * The allowed headers are passed to the browser to specify which
     429                 * headers can be passed to the REST API. By default, we allow the
     430                 * Content-* headers needed to upload files to the media endpoints.
     431                 * As well as the Authorization and Nonce headers for allowing authentication.
     432                 *
     433                 * @since 5.5.0
     434                 *
     435                 * @param string[] $allow_headers The list of request headers to allow.
     436                 * @param WP_REST_Request The request in context.
     437                 */
     438                $allow_headers = apply_filters( 'rest_allowed_cors_headers', $allow_headers, $request );
     439
     440                $this->send_header( 'Access-Control-Allow-Headers', implode( ', ', $allow_headers ) );
    438441
    439442                $result = $this->check_authentication();
  • trunk/tests/phpunit/tests/rest-api/rest-server.php

    r55822 r56096  
    22012201        }
    22022202
     2203        /**
     2204         * @ticket 57752
     2205         */
     2206        public function test_rest_exposed_cors_headers_filter_receives_request_object() {
     2207                $mock_hook = new MockAction();
     2208                add_filter( 'rest_exposed_cors_headers', array( $mock_hook, 'filter' ), 10, 2 );
     2209
     2210                rest_get_server()->serve_request( '/test-exposed-cors-headers' );
     2211
     2212                $this->assertCount( 1, $mock_hook->get_events() );
     2213                $this->assertCount( 2, $mock_hook->get_events()[0]['args'] );
     2214                $this->assertInstanceOf( 'WP_REST_Request', $mock_hook->get_events()[0]['args'][1] );
     2215                $this->assertSame( '/test-exposed-cors-headers', $mock_hook->get_events()[0]['args'][1]->get_route() );
     2216        }
     2217
     2218        /**
     2219         * @ticket 57752
     2220         */
     2221        public function test_rest_allowed_cors_headers_filter_receives_request_object() {
     2222                $mock_hook = new MockAction();
     2223                add_filter( 'rest_allowed_cors_headers', array( $mock_hook, 'filter' ), 10, 2 );
     2224
     2225                rest_get_server()->serve_request( '/test-allowed-cors-headers' );
     2226
     2227                $this->assertCount( 1, $mock_hook->get_events() );
     2228                $this->assertCount( 2, $mock_hook->get_events()[0]['args'] );
     2229                $this->assertInstanceOf( 'WP_REST_Request', $mock_hook->get_events()[0]['args'][1] );
     2230                $this->assertSame( '/test-allowed-cors-headers', $mock_hook->get_events()[0]['args'][1]->get_route() );
     2231        }
     2232
    22032233        public function _validate_as_integer_123( $value, $request, $key ) {
    22042234                if ( ! is_int( $value ) ) {
Note: See TracChangeset for help on using the changeset viewer.