So, what do you know about the WordPress REST API? If you’re like me, the answer is “not much”. So it came out of the blue when a friend of mine contacted me last week about problems he was having with the REST API.
The Issues
1) The URL https://www.example.com/wp-json/wp/v2/users can return information about ALL the users in your WordPress installation – Administrators, Authors, Full Names, whatever. This is a MAJOR security flaw. WordPress has been stealthily and silently upgrading files automatically to fix tis issue (Can you say “Supply Chain Infection?). In a properly updated site the site should respond with a JSON-like message like this:
{“code”:”rest_user_cannot_view”,”message”:”Sorry, you are not allowed to list users.”,”data”:{“status”:401}}
2) The URL https://www.example.com/wp-json/ simply returns an enormous amount of data for most installations. This includes all the REST API namespaces and endpoints, among other things.
In the worst case, an attacker doesn’t even need to guess what you’re running. Why make it so easy for hackers? And attack they will.
In the best case, it subjects your site to easy Denial-of-Service attacks. “/wp-json” is 8 characters appended to your website root. The response can be in the Megabytes. This is likely to be invisible to most WordPress site owners since it just looks like inconspicuous WordPress internals. Your site will simply appear to be sluggish and unresponsive.
Mitigation
1) In the case of #1 above, WordPress may automatically upgrade the affected files in your installation automatically. I personally have an issue with that but it is better than doing nothing.
In all cases, patched or not, I recommend that you install a good security plugin that can monitor access to WordPress REST Namespaces. I’ve had good success with WP-Cerber.
CHANGE YOUR ADMIN USER NAME(S).
2) I’ve seen installations that still render the /wp-json/ URL even with WP-Cerber. In these cases, please create the following entries in your .htaccess file, BEFORE the default WordPress entries:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_ADDR} !^127.0.0.1$
RewriteRule “wp-json($|/$)” “-” [F]
</IfModule>
Access from localhost (127.0.0.1) is unaffected. Otherwise, URLs ending in wp-json or wp-json/ (exactly) are Forbidden. Since this error is generated by Apache, you *might* also make sure that you don’t give up Apache Versions and the underlying O/S. See my earlier post on Hardening Apache Server.
3) For the Super-Paranoid (and you might be, by now), the following .htaccess file entries will block ALL requests under the REST Namespace:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_ADDR} !^127.0.0.1$
RewriteRule “wp-json($|/.*)” “-” [F]
</IfModule>
File Changes
1) On a WordPress 5.6 installations, the following files in wp-includes were observed to be upgraded:
238045 Sep 9 00:08 functions.php
92487 Sep 9 00:08 script-loader.php
766 Sep 9 00:08 version.php
2) On a WordPress 5.7 installation, the following files in wp-includes were observed to be upgraded:
212923 Sep 9 00:23 class-wp-xmlrpc-server.php
241057 Sep 9 00:23 functions.php
98208 Sep 9 00:23 script-loader.php
766 Sep 9 00:23 version.php
3) On a WordPress 5.8 installation, the following files in wp-includes were observed to be upgraded:
16999 Sep 9 00:00 block-editor.php
36535 Sep 9 00:00 blocks.php
71193 Sep 9 00:00 class-wp-customize-widgets.php
16586 Sep 9 00:00 class-wp-image-editor.php
33739 Sep 9 00:00 class-wp-theme-json.php
11464 Sep 9 00:00 class-wp-theme-json-resolver.php
12087 Sep 9 00:00 compat.php
253122 Sep 9 00:00 functions.php
108457 Sep 9 00:00 script-loader.php
5326 Sep 9 00:00 theme.json
766 Sep 9 00:00 version.php
Privacy
Despite the file changes, the systems remained at their WordPress Release levels. However, when upgrading to 5.8.1 the user is presented a screen which has a Privacy Notice Tab. This clearly states that your WordPress installation will be contacting WordPress regularly for updates.
I wish WordPress would update their regular Privacy Page to reflect this operation.
Other REST Queries of Interest
/wp-json/wp-site-health/v1/
/wp-site-health/v1/tests/background-updates
/wp-json/wp-site-health/v1/tests/https-status
/wp-json/wp/v2/posts
/wp-json/wp/v2/media
/wp-json/wp/v2/categories
/wp-json\/oembed/1.0/embed
/wp-json/wp/v2/pages
Conclusion
Everybody that has, or manages, a WordPress site should do some tests and take appropriate mitigation steps. WordPress, while clearly trying to fix REST API issues (as stated in the 5.8.1 Release Notes) surely has a lot more explaining to do. I had experienced Supply Chain Infections from WordPress.com many years ago. Even worse, using WordPress.com, I’d fix it and then their backup/restore shoved the infection right back in again.
Am I to believe that WordPress.org is going to be any better than WordPress.com? This s**t stinketh. Nag me if you must, but leave my files alone.
Jared Hall
September 16, 2021 @ 11:48 am
Silence is Golden? Not.
Thank you to all of the reporters for privately disclosing the vulnerabilities. This gave the WordPress security team time to fix the vulnerabilities before WordPress sites could be attacked.