This post is one of many examples of how broad information security is as a discipline. One of the hallmarks of security is mitigation. We create configurations, policies, and code to ensure that attacks and exploits don’t happen, and if they do that they not be allowed to cause maximum damage.
The website I’m looking at today belongs to a major information security consultancy. They work with many Fortune 100s and thousands of SMBs. They do everything from threat modelling to network monitoring to penetration testing to compliance. Their core competency is security and it’s in their DNA.
Mitigating username validation
When you first visit this company’s website, it looks characteristically WordPress. Viewing the page source, you see that it’s indeed running WordPress. Managed WordPress deployments by Automattic are pretty good; they have a great team behind the scenes, participate in bug bounties, keep everything up-to-date and rely on their enterprise-ready infrastructure. This blog is hosted with them! It’s not perfect, but nothing is. It’s pretty good though. To check whether it’s self-hosted or managed, I simply run dig. The IP isn’t Automattic’s, so it’s likely self-hosted.
First thing I do is try to find the admin login page, which was easy because this company kept it at /wp-admin. I try a dummy username and password to see what the authentication feedback is and I get the following:
What this company did was change the WordPress source responsible for generating this message and they removed it. This isn’t difficult to do, but it does demonstate that the authentication feedback message shouldn’t be shown. By default, WordPress will tell you when authentication failed, if it fails. Again, to highlight, the intent here is to hide that information and this company took to modifying the WordPress source to do it. In some form or another, this matters to them.
This is done to prevent attackers from validating certain usernames and using it to launch a brute force attack. After all, a password is usually the weakest link and with enough time and leeway, it can be gussed by a machine.
The above strategy makes sense and is one way to implement the mitigation. However, this company didn’t take into consideration other ways by which usernames can be validated. The WordPress API, by default, returns a list of all users with at least 1 post when a GET request is made to /wp-json/wp/v2/users.
This company doesn’t want folks validating usernames so they remove the feedback message from the WordPress source, but the mitigation is fully defeated because the API is left unsecured.
Can’t catch it all
The above example is just that – an example. It shows a time when a company is trying to prevent something, but they leave something open that circumvents their mitigation attempts. Whether it’s network or software security, you have to understand the bigger picture, know what you’re trying to secure, understand the configurations you select, have a thorough discussion about ways the mitigation could be circumvented, and have a plan for the worst-case scenario where you tried to mitigate something but fell short.
This particular security company isn’t at much increased risk. Being able to validate a username is the first of many steps. As it is, this unsecured API isn’t a threat or an exploit, but it defeats the company’s security intent and purpose. The real issue is when, for example, you think you’ve mitigated ARP poisioning, but you haven’t really. What happens then? What about when you think you’ve mitigated SQL injection, but you haven’t really? That’s a problem, and it’s what results in most massive breaches. Think beyond the box and understand a real attacker will find every and any hole.