Opened 20 hours ago
Last modified 3 hours ago
#65839 new defect (bug)
Site Health REST API test can fail with rest_cookie_invalid_nonce when full browser cookie jar is sent
| Reported by: | hamishwright | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | Site Health | Version: | 7.0.3 |
| Severity: | minor | Keywords: | rest-api false-positive site-health has-patch has-unit-tests |
| Cc: | Focuses: | tests, rest-api |
Description (last modified by )
WordPress Site Health can falsely report the REST API as failing with:
REST API Endpoint: https://example.com/wp-json/wp/v2/types/post?context=edit
REST API Response: (403) Forbidden
The REST response body is:
{"code":"rest_cookie_invalid_nonce","message":"Cookie check failed","data":{"status":403}}
In WP_Site_Health::get_test_rest_availability(), core builds the loopback request using:
<?php $cookies = wp_unslash( $_COOKIE ); $r = wp_remote_get( $url, compact( 'cookies', 'headers', 'timeout', 'sslverify' ) );
This sends the entire browser cookie jar to the REST endpoint, not just WordPress authentication cookies.
On the affected site, a diagnostic confirmed:
WordPress auth cookies only -> 200
WP_Http_Cookie objects only -> 200
Explicit Cookie header only -> 200
Full $_COOKIE jar, as Site Health -> 403 rest_cookie_invalid_nonce
The full cookie jar included unrelated cookies from analytics, LiteSpeed, Cloudflare, WooCommerce, Sourcebuster, Jetpack, wp-settings-*, and others. When the outgoing Site Health REST loopback request was filtered to include only:
wordpress_logged_in_*
wordpress_sec_*
wordpress_test_cookie
the Site Health REST API warning cleared immediately.
Expected behavior:
Site Health’s authenticated REST loopback test should only send the WordPress cookies required for authentication, or otherwise avoid allowing unrelated browser cookies to interfere with REST nonce/cookie validation.
Actual behavior:
Site Health passes all of $_COOKIE into the loopback request.A sufficiently large or otherwise problematic browser cookie jar can cause the REST API availability test to return a false 403, even though the REST endpoint and WordPress authentication cookies are working correctly.
Suggested fix:
In WP_Site_Health::get_test_rest_availability(), filter $cookies before passing them to wp_remote_get() so only WordPress authentication/test cookies are sent.
Change History (2)
This ticket was mentioned in PR #12952 on WordPress/wordpress-develop by @khokansardar.
3 hours ago
#2
- Keywords has-patch has-unit-tests added
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Restricts the cookies sent with the Site Health REST API availability test to the cookie names WordPress itself defines, instead of forwarding the visitor's entire browser cookie jar to the loopback request.
What the problem was:
WP_Site_Health::get_test_rest_availability()passedwp_unslash( $_COOKIE )straight towp_remote_get(), so every cookie in the visitor's browser — analytics, CDN, cache, commerce, and others — was forwarded to the site's own REST endpoint.X-WP-Nonceheader.(403) Forbiddenwithrest_cookie_invalid_nonce, while the same request limited to the WordPress cookies returned200.What the fix does:
$cookiesthrougharray_intersect_key()so onlyAUTH_COOKIE,SECURE_AUTH_COOKIE,LOGGED_IN_COOKIE, andTEST_COOKIEare forwarded.Approach and why:
wordpress_name prefix. A prefix would keepwp-settings-*, which is not an authentication cookie, and would break on sites that redefine the cookie constants inwp-config.php. The test covers thewp-settings-*case specifically.http_request_argsfilter, which runs after this code. No new filter is introduced.WP_Site_Health::can_perform_loopback(),WP_Automatic_Updater, andwp-admin/includes/file.phpuse the samewp_unslash( $_COOKIE )pattern for different loopback targets and need their own analysis; they are left for a separate ticket.Testing instructions:
_ga,wp-settings-time-1, and a large dummy cookie of a few kilobytes).(403) Forbiddenwithrest_cookie_invalid_nonce.phpunit --filter test_get_test_rest_availability_sends_only_wordpress_cookies tests/phpunit/tests/admin/wpSiteHealth.php. The test fails on trunk and passes with the patch.## Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Ticket analysis, code implementation, and tests. All changes were reviewed and validated by me.
---
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.