I am considering to improve security of my Wordpress website, and in doing so have come across WP REST API being enabled by default (since WP 4.4 if I'm not mistaken).
What is a safe way to disable it?
By "safe" here I mean that it does not cause unexpected side-effects, e.g. does not break any other WP core functionality.
One possible approach would be to use .htaccess
rewrite rules, but surprisingly I haven't found any 'official' instructions on doing so.
Any help or recommendation is greatly appreciated :)
Update:
3rd-party plugins is not the solution I am looking for. Although I'm aware there are plenty of them that solve the task, they include many extra features that slow down the website. I would hope there is a one-line solution to this problem without the overhead of an extra plugin.
Update 2:
Here is the official opinion of Wordpress: https://developer.wordpress.org/rest-api/using-the-rest-api/frequently-asked-questions/#can-i-disable-the-rest-api
According to this, the Wordpress team wants future WP functionality to depend on the new REST API. This means there is no guaranteed safe way to disable the REST API.
Let's just hope there are enough security experts taking care of WP security.
Update 3:
A workaround is presented in WordPress API Handbook - you can Require Authentication for All Requests
This makes sure that anonymous access to your website's REST API is disabled, only authenticated requests will work.
From the author original question I've chosen option 2 that came from wordpress official recommendations(https://developer.wordpress.org/rest-api/using-the-rest-api/frequently-asked-questions/#can-i-disable-the-rest-api). So just put in your functions.php to let only logged in users use the rest api:
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( ! is_user_logged_in() ) {
return new WP_Error( 'rest_not_logged_in', 'You are not currently logged in.', array( 'status' => 401 ) );
}
return $result;
});
You can disable it for requests other than localhost:
function restrict_rest_api_to_localhost() {
$whitelist = [ '127.0.0.1', "::1" ];
if( ! in_array($_SERVER['REMOTE_ADDR'], $whitelist ) ){
die( 'REST API is disabled.' );
}
}
add_action( 'rest_api_init', 'restrict_rest_api_to_localhost', 0 );
Disabling REST API was not a bad idea, after all.
It actually opened a huge hole in all websites!
In wordpress 4.4 there was a way
Here, I've found a possible solution with .htaccess
but should be carefully tested in combination with whatever else is in your .htaccess
file (e.g., pretty-url rules added by wordpress itself):
# WP REST API BLOCK JSON REQUESTS
# Block/Forbid Requests to: /wp-json/wp/
# WP REST API REQUEST METHODS: GET, POST, PUT, PATCH, DELETE
RewriteCond %{REQUEST_METHOD} ^(GET|POST|PUT|PATCH|DELETE) [NC]
RewriteCond %{REQUEST_URI} ^.*wp-json/wp/ [NC]
RewriteRule ^(.*)$ - [F]
A very drastic method, is also to have a 404.html
webpage in your root and then add this line:
# WP REST API BLOCK JSON REQUESTS
# Redirect to a 404.html (you may want to add a 404 header!)
RewriteRule ^wp-json.*$ 404.html
Note that, unless you use a static page, i.e., not involved with wordpress functions, if you want to return a 404
error with an appropriate error page, this is a complete separate topic, with a lot of issues when Wordpress is involved
With the plugin "Disable REST API" you can select which APIs you want to enable, e.g. the contact form 7 API. See the plugin's settings (yoursite.com/wp-admin/options-general.php?page=disable_rest_api_settings)