Safely disable WP REST API

2020-05-15 15:22发布

问题:

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 Reque​sts

This makes sure that anonymous access to your website's REST API is disabled, only authenticated requests will work.

回答1:

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;
});


回答2:

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 );


回答3:

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



回答4:

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)