Modest Tools

OWASP Top Ten in Simple Terms: Access Control

· Alex P.

OWASP is an online community that produces freely available articles, methodologies, documentation, tools, and technologies in the field of web application security. The OWASP Top Ten is a list of the most critical security risks to web applications. In this series of articles, I will try to explain each of the Top Ten risks in simple terms.

Broken Access Control

Access control is the process of deciding who is allowed to do what in a system. It is a fundamental part of security. If access control is broken, it means that users can do things they are not supposed to do. Like, for example, viewing other person’s private profile or making API calls that they are not supposed to make.

A couple of examples

  1. Imagine you have a website where each user has a profile page that only they should be able to see. Let’s say the URL of the profile page is https://example.com/user/123. If you change the 123 to 124, you should not be able to see the profile of user 124. But if you can, then the access control is broken. The system is supposed to check if you are the owner of the profile before showing it to you.

Note: For this reason, numeric IDs are somewhat insecure compared to UUIDs. Even with proper access control, having incremental IDs can expose sensitive information. Like how many users you have, how many orders you have daily, etc. It’s pretty much impossible to guess what the next UUID will be, but it’s very obvious what the next numeric ID will be.

  1. Imagine you have an API that allows users to update their profile. If you can update someone else’s profile, then the access control is broken. Even if properly hiding the UI elements that allow you to do that, you still need to check permissions for every API call. Otherwise anyone capable of making calls with curl or Postman can break your application.

  2. Imagine you have an admin panel that only admins should be able to access. If your only protection from unauthorized access is hoping that no one will find the URL, then your access control is broken. You’ll need to implement roles, permissions or some other form of authorization.

Why is this a number one most frequent risk?

In 2021 Broken Access Control was the most frequent risk in the OWASP Top Ten. In my personal experience, it is also the most common vulnerability I see in web applications. For this I have a couple of theories:

  1. Broken access control is not obvious. It’s not like you’re missing a feature or have your page crashing every time you load it. It’s a subtle vulnerability few developers and even QA engineers think about. Seriously, how many times have you tried messing with your app’s URLs to see if you can access something you’re not supposed to?

  2. Access control is an afterthought. All of us are super busy shipping features, fixing critical bugs, and dealing with the never-ending stream of meetings. Adding access control to the endless TODO list is not something you get excited about.

  3. SPA architecture makes it harder. Single Page Applications (SPAs) are all the rage these days. There is a whole generation of developers who think that a web app starts with installing React and ends with deploying to Netlify. Do you know many frontend routers that prioritize access control? I don’t. How often do you see a developers checking permissions before rendering a component?

  4. SPAs make it harder (part 2). In the age of server-side rendering, it was easier to keep track of what is allowed and what is not. You had a server that would check permissions and render the page accordingly. With SPAs, you have to check permissions on the client side. You also have to check permissions on the server side. And you have to make sure that the client side and the server side are in sync.

  5. SPAs make it harder (part 3). Think about the data you get from backend APIs. It’s quite obvious what kind of information you expose when what you send to the browser is a complete HTML page. But what about JSON? Do you just get an object from the database and send it to the client? Do you explicitly filter out sensitive or simply unnecessary information? Probably not. On the flip side it saves you time adding new fields every time someone on the frontend asks for them. But it also makes it easier for someone to get access to information they’re not supposed to see.

What to do about it?

Honestly, I don’t feel like I have a good answer to this question. Access control is hard to get right. But I would approach it keeping in mind the following:

  1. Try to keep the app simple. The smaller the app, the less surface area for vulnerabilities. I honestly think that technical teams should more often say “no” to features. Especially those that give only a small boost in user experience but add a lot of complexity to the codebase.

  2. Keep access control simple. If you only have two roles in your app, you don’t need a complex permission management system. Remember YAGNI (You Ain’t Gonna Need It).

  3. Have rigorous QA. I don’t buy the idea of engineers testing their own code. Unit-testing, sure, but when it comes to E2E and regression testing, I think you need a dedicated QA engineer. Trusting a developer to test their own access control is like trusting a bank with their own financial audit.

  4. Have a security audit. If you can afford it. These are expensive, but if you’re an established and profitable business, it’s a good investment. A security audit can find vulnerabilities that you would never think of.

  5. Be a little paranoid. If you’re building a brand new system, try to go the paranoid route. Assume that every request can be malicious. Trust no one. Not a single frontend redirect, not a single API call. This is a good mindset to have when building a new system.

Conclusion

Broken access control is the most common way to mess up security-wise. Modern web apps are getting increasingly complex, and access control is just slipping through the cracks. But it’s not impossible to get it right. Especially if you keep it simple, have good QA, and maybe even a security audit once in a while.