Closing the json-leak in WordPress

I ran into this little tip in a magazine I often read, the Dutch c’t and I thought it might be interesting for people reading this blog as many have their own WordPress blog and of course for myself to easily find it back :-).

WordPress has a JSON API which gives access to all parts of your WordPress site. What many people (including me till recently) don’t know is that this includes all your draft posts, unpublished media and even parts of your site which you might have password protected. And that without entering a password. If you want to see if your site is susceptible, just type your blog url with /wp-json behind it. It might also be something like <url>/index.php/wp-json. If you get a lot of json back, you can try the see all media through <url>/wp-json/wp/v2/media. <url>/wp-json/wp/v2/pages should give all pages, <url>/wp-json/wp/v2/posts als posts including drafts. If it does and you find that undesirable (and I think you should), there are luckily ways to fix it.

The article provided several solutions to closing this loophole. One way could be to disable the JSON API, but this gives problems if you use the Gutenberg editor which uses it. Another solution could be to add authentication to /wp-json on your webserver. They also supplied code to add the the functions.php to solve the problem. You need to find the functions.php for the theme which you currently use. The solution is in putting a filter in this file. I added it somewhere to the bottom:

add_filter( 'rest_authentication_errors', function( $result ) {

if ( ! empty( $result ) ) {
   return $result;
}

if ( ! is_user_logged_in() ) {
   return new WP_Error( '401', 'not allowed.', array('status' => 401) );
}

return $result;

});

Beware though that you might have to repeat this when you update your theme!