admin管理员组

文章数量:1122846

I recently discovered that the REST API in Wordpress is completely open, and all users's accounts are publicly queriable. I have many many users and I cant have anyone getting their emails and names. Also, I have some custom fields (which is also queriable with the API) holding somewhat sensitive information that only certain (paying) users can access.

Since Wordpress recommends against closing the API completely because it may break the website, how can I safely disable it? Ideally no one, not even my admins end editors should be able to access, let alone my customers regardless if logged in or not, but everywhere I look people only teach how to hide the API for unlogged users. This is quite useless to me since anyone can sign up to my website and then see it.

I thought about disabling it for everyone but admins (so as not to break the wp-admin area), but someone pointed out that some plugins may rely on the API for front end stuff.

This is the code I came up with that does that

function RestrictRestAPI($result) 
{
    if (true === $result || is_wp_error($result)) { return $result; }

    if (is_user_logged_in()) 
    {
        $user = wp_get_current_user();

        if ($user && (in_array('administrator', $user->roles) || in_array('editor', $user->roles))) 
        { return $result; }
        else 
        { return new WP_Error('rest_forbidden', __('You do not have permissions to access this API.'), array('status' => 403)); } 
    } 
    else 
    { return new WP_Error('rest_forbidden', __('You do not have permissions to access this API.'), array('status' => 403)); }
} 
add_filter('rest_authentication_errors', 'RestrictRestAPI');

(yes it enables the API for users with the editor role too, I have two moderators with role that use the wp-admin panel)

Whats the best course of action here?

I recently discovered that the REST API in Wordpress is completely open, and all users's accounts are publicly queriable. I have many many users and I cant have anyone getting their emails and names. Also, I have some custom fields (which is also queriable with the API) holding somewhat sensitive information that only certain (paying) users can access.

Since Wordpress recommends against closing the API completely because it may break the website, how can I safely disable it? Ideally no one, not even my admins end editors should be able to access, let alone my customers regardless if logged in or not, but everywhere I look people only teach how to hide the API for unlogged users. This is quite useless to me since anyone can sign up to my website and then see it.

I thought about disabling it for everyone but admins (so as not to break the wp-admin area), but someone pointed out that some plugins may rely on the API for front end stuff.

This is the code I came up with that does that

function RestrictRestAPI($result) 
{
    if (true === $result || is_wp_error($result)) { return $result; }

    if (is_user_logged_in()) 
    {
        $user = wp_get_current_user();

        if ($user && (in_array('administrator', $user->roles) || in_array('editor', $user->roles))) 
        { return $result; }
        else 
        { return new WP_Error('rest_forbidden', __('You do not have permissions to access this API.'), array('status' => 403)); } 
    } 
    else 
    { return new WP_Error('rest_forbidden', __('You do not have permissions to access this API.'), array('status' => 403)); }
} 
add_filter('rest_authentication_errors', 'RestrictRestAPI');

(yes it enables the API for users with the editor role too, I have two moderators with role that use the wp-admin panel)

Whats the best course of action here?

Share Improve this question edited Jun 25, 2024 at 21:04 Ravi Mattar asked Jun 25, 2024 at 20:57 Ravi MattarRavi Mattar 1013 bronze badges 2
  • Names and emails are not exposed to logged out users. – Jacob Peattie Commented Jun 26, 2024 at 4:14
  • Hi @JacobPeattie, as I stated in the question, access to that endpoint being restricted to logged in users is still a problem for me. – Ravi Mattar Commented Jul 5, 2024 at 20:56
Add a comment  | 

1 Answer 1

Reset to default 2

You can use the rest_dispatch_request filter to catch the /wp/v2/users routes before they deliver their data to the user.


add_filter( 'rest_dispatch_request', 'wpse425815_authenticate_user_route', 10, 4 );
/**
 * Forces authentication on the wp/v2/user route(s).
 *
 * @param  mixed      $result  The current result.
 * @param  WP_Request $request The REST request.
 * @param  string     $route   The requested route.
 * @param  array      $handler The REST handler.
 * @return mixed|WP_Error      Error if unpermitted; otherwise return $result.
 */
function wpse425815_authenticate_user_route( $result, $request, $route, $handler ) {
    if (
        false !== strpos( $route, '/wp/v2/users' ) &&
        ! current_user_can( 'edit_others_posts' )
    ) {
        return new \WP_Error(
            'rest_auth_required',
            'Authentication required',
            array( 'status' => 401 )
        );
    }
    return $result;
}

I've tried this code on a local installation, and it seems to do what you're asking (ie, only allow authenticated users at Editor and above to view the /wp/v2/users REST data) disables direct, unauthenticated access to the /wp/v2/users route (eg https://example.com/wp-json/wp/v2/users` will return a 401) and disables use by the backend of user data for users below Editor level (eg, this disables specifying the author of a post in the Block Editor).

Test it before you use it in production.

References

  • rest_dispatch_request filter
  • current_user_can()

This answer builds on the code snippet provided here: https://rinat.dev/blog/2020/03/04/how-to-lock-down-wordpress-rest-api-endpoints-or-completely-disable-them/#rest-dispatch-request .

本文标签: pluginsIs it a good idea to restrict the REST API