Published on

WordPress Security: leaking data trough the Rest API

WordPress being one of the most popular CMS in the world, it is a prime target for hackers as the scope of discovering a new vulnerability can be great. Automated attacks are legion, which any webmaster must have already noticed by exploring the logs of HTTP requests received by their server.

Protecting yourself from automated attacks

Don't panic though, if you follow good practices in terms of hosting, updating the CMS and its plugins as well as limiting their number, you're already much better equipped than a large part of WordPress users and therefore out of reach of the majority of non-targeted attacks.

But an attack is not just a collection of technical flaws. It is first and foremost reconnaissance, information recovery and then exploitation.

Data exposed via WordPress API

What if I told you there was an intruder lurking deep within WordPress that had the potential to expose your most closely guarded secrets?

Since version 4.7.0 of WordPress, it comes with a Rest API that allows the retrieval of content accessible to anonymous users, but also to perform CRUD type operations on the CMS resources once authenticated.

A real step forward at the time of its release, the Rest API is now an integral part of WordPress and is used by a large number of plugins. It also provides the data necessary for Gutenberg to function.

However, even though this is very practical, it is often ignored by developers when developing authorization features, potentially leaking data that needs to be protected.

Let’s take a quick look at the things to keep in mind when developing a project with WordPress.

WordPress users enumeration

https://developer.wordpress.org/rest-api/reference/users/#list-users

/wp-json/wp/v2/users

By going to this url, you will find the list of users of your WordPress site. Even if I am sure that you have a complex password with varied characters, perhaps this is not the case for your webmaster, your editor or your project manager who has access to your site?

Rather than brute-forcing the username and password to try to break into your site, it is trivial to retrieve the users of a site and then perform a dictionary attack to crack the most commonly used passwords.

So be careful, even if your username is just a collection of random characters, it is very easily recoverable by anyone with a web browser. Always prefer using a strong password rather than resorting to security through obscurity.

Media Library File Listings

https://developer.wordpress.org/rest-api/reference/media/#list-media

/wp-json/wp/v2/media?_fields=source_url&per_page=100
/wp-json/wp/v2/media?_fields=source_url&per_page=100&search=zip
/wp-json/wp/v2/media?_fields=source_url&per_page=100&search=pdf
/wp-json/wp/v2/media?_fields=source_url&per_page=100&search=xls

ALL files added to the WordPress library from its admin interface are visible to anyone.

If there is only one thing to remember from this article, it is this. So I repeat, all files added to the WordPress library from its admin interface are visible to anyone.

With the urls above it is possible to navigate through media, perform searches, show only zip, pdf files, etc.

While listing server folders is most often disabled when hosting a WordPress site with an nginx or Apache server, listing via the API is a gray area for many developers who are completely unaware of this possibility.

By accidentally typing this kind of URLs while browsing the web, I have already come across:

  • VOD or online course sites that allowed their video files to be listed via the API
  • internal sites protected by password on the front end but not protecting certain confidential documents hosted there
  • screenshots showing user credentials.

(All site owners have been informed of these issues which are now fixed)

Conclusion

As you can see, the goal of this article is to educate developers, webmasters, and site owners about what is private and what is public on a site. While it's easy to see when you're accessing a page you shouldn't be by simply opening its URL in a browser, I can imagine that it's a bit more tedious to check it for each route in the WordPress Rest API.

But as web uses and practices evolve to allow more interactivity and communication between different systems via APIs, we should evolve with them and have the reflex to think omnichannel for all developments carried out on a site, whether it is a WordPress site or not.

As an added step to design and specification conformity checks, consider having a deep look into what your API is exposing too.