WordPress Rest API — Locked Down

The WordPress Rest API is exposed to the public by default and maybe that isn’t something you’re too happy about, and to be fair, it can be a bit of a security vulnerability when it comes to the users endpoint. Being able to see a list of all users and what is most probably their usernames, means half the job is done for any hacker, as they’ll only need to crack your password.

So with that said, here is a tidy little function that will restrict access to the API for only logged in users.

add_filter('rest_authentication_errors', 'lockdown_that_wp_rest_api'); function lockdown_that_wp_rest_api( $errors ) { if( !is_user_logged_in() ) return new WP_Error( 'forbidden_access', 'Access denied', array( 'status' => 403 )); return $errors; }

It hooks into the rest_authentication_errors filter which allows us to add our own check. We use this to return a new WP_Error if the current user is not logged in. To the website user that would look like this.

{ code: "forbidden_access", message: "Access denied", data: { status: 403 } }

Warning. Some plugins use the API to function. For instance, the Contact Form 7 plugin uses the API to submit forms. Thankfully, there is a way to lock down the API but still allow access to certain endpoints. Here is the above function again, but we’re allowing access to the Contact Form 7 endpoint.

add_filter('rest_authentication_errors', 'lockdown_that_wp_rest_api'); function lockdown_that_wp_rest_api( $errors ) { if( !strpos($_SERVER['REQUEST_URI'], 'contact-form-7') && !is_user_logged_in() ) return new WP_Error( 'forbidden_access', 'Access denied', array( 'status' => 403 )); return $errors; }

See how we use the PHP strpos function to detect an endpoint in the path string. To allow other endpoints, you would use the same approach but include your use case.

That’s it folks. Nice and easy.

;