From ac9cc8341f826fcb160402c7277f3ce4f1a40a3e Mon Sep 17 00:00:00 2001 From: audrasjb Date: Thu, 12 Oct 2023 13:15:24 +0000 Subject: [PATCH] REST API: Ensure no-cache headers are sent when methods are ovverriden. Props tykoted, xknown, ehtis, timothyblynjacobs, peterwilsoncc, rmccue, jorbin. Merges [56834] to the 6.3 branch. Built from https://develop.svn.wordpress.org/branches/6.3@56841 git-svn-id: http://core.svn.wordpress.org/branches/6.3@56353 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/rest-api.php | 1 + wp-includes/rest-api/class-wp-rest-server.php | 42 +++++++++++-------- wp-includes/version.php | 2 +- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/wp-includes/rest-api.php b/wp-includes/rest-api.php index a8a2aac177..1325228d41 100644 --- a/wp-includes/rest-api.php +++ b/wp-includes/rest-api.php @@ -1084,6 +1084,7 @@ function rest_cookie_check_errors( $result ) { $result = wp_verify_nonce( $nonce, 'wp_rest' ); if ( ! $result ) { + add_filter( 'rest_send_nocache_headers', '__return_true', 20 ); return new WP_Error( 'rest_cookie_invalid_nonce', __( 'Cookie check failed' ), array( 'status' => 403 ) ); } diff --git a/wp-includes/rest-api/class-wp-rest-server.php b/wp-includes/rest-api/class-wp-rest-server.php index 9df4556ada..7fca867b0a 100644 --- a/wp-includes/rest-api/class-wp-rest-server.php +++ b/wp-includes/rest-api/class-wp-rest-server.php @@ -322,24 +322,6 @@ class WP_REST_Server { */ $this->send_header( 'X-Content-Type-Options', 'nosniff' ); - /** - * Filters whether to send nocache headers on a REST API request. - * - * @since 4.4.0 - * - * @param bool $rest_send_nocache_headers Whether to send no-cache headers. - */ - $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() ); - if ( $send_no_cache_headers ) { - foreach ( wp_get_nocache_headers() as $header => $header_value ) { - if ( empty( $header_value ) ) { - $this->remove_header( $header ); - } else { - $this->send_header( $header, $header_value ); - } - } - } - /** * Filters whether the REST API is enabled. * @@ -394,10 +376,12 @@ class WP_REST_Server { * $_GET['_method']. If that is not set, we check for the HTTP_X_HTTP_METHOD_OVERRIDE * header. */ + $method_overridden = false; if ( isset( $_GET['_method'] ) ) { $request->set_method( $_GET['_method'] ); } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { $request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ); + $method_overridden = true; } $expose_headers = array( 'X-WP-Total', 'X-WP-TotalPages', 'Link' ); @@ -498,6 +482,28 @@ class WP_REST_Server { */ $served = apply_filters( 'rest_pre_serve_request', false, $result, $request, $this ); + /** + * Filters whether to send nocache headers on a REST API request. + * + * @since 4.4.0 + * @since 6.3.2 Moved the block to catch the filter added on rest_cookie_check_errors() from rest-api.php + * + * @param bool $rest_send_nocache_headers Whether to send no-cache headers. + */ + $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() ); + + // send no cache headers if the $send_no_cache_headers is true + // OR if the HTTP_X_HTTP_METHOD_OVERRIDE is used but resulted a 4x response code. + if ( $send_no_cache_headers || ( true === $method_overridden && strpos( $code, '4' ) === 0 ) ) { + foreach ( wp_get_nocache_headers() as $header => $header_value ) { + if ( empty( $header_value ) ) { + $this->remove_header( $header ); + } else { + $this->send_header( $header, $header_value ); + } + } + } + if ( ! $served ) { if ( 'HEAD' === $request->get_method() ) { return null; diff --git a/wp-includes/version.php b/wp-includes/version.php index c5fe88d8d6..7b380a4c3a 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.3.2-RC1-56840'; +$wp_version = '6.3.2-RC1-56841'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.