Opened 2 years ago
Closed 2 years ago
#52104 closed defect (bug) (duplicate)
False positive REST API error in Site Health when triggered by wp_site_health_scheduled_check event
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 5.6 |
Component: | Site Health | Keywords: | |
Focuses: | Cc: |
Description
I'm using system cron (DISABLE_WP_CRON = true) but I think cron type doesn't matter (system or WP Cron) and filter requests to REST API to allow only logged in users.
<?php add_filter('rest_authentication_errors', 'force_rest_auth'); function force_rest_auth($result) { if(!empty($result)) return $result; if(!is_user_logged_in()) return new WP_Error('rest_not_logged_in', __('Only authenticated users can access the REST API.', 'security-hardener'), array('status' => 401)); return $result; }
Cron events are executed with unknown user (ID 0), when a scheduled check is made for type post caps:
/wp-json/wp/v2/types/post?context=edit
response code is 401 (raw response):
{"code":"rest_forbidden_context","message":"Sorry, you are not allowed to edit posts in this post type.","data":{"status":401}}
this causes false results in Site Health dashboard widget. When Site Health isn't triggered manually from wp-admin I get 2 errors in dashboard widget, but when I enter Site Health from wp-admin, only 1 error is shown.
If i hit:
/wp-json/wp/v2/types/post?context=edit
or
/wp-json/
in incognito tab (not logged in), both endpoints return my custom 401 error for not logged in users so my code works fine, but when I hit those endpoints in normal tab (I'm logged in):
/wp-json/
recognizes me and returns proper result but:
/wp-json/wp/v2/types/post?context=edit
doesn't recognize me:
<?php if ( 'edit' === $request['context'] && ! current_user_can( $obj->cap->edit_posts ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); }
current_user_can() check in get_item() method of class WP_REST_Post_Types_Controller returns false.
Related: #52112