Interesting that "broken access controls" made it into the top spot. Not sure if this anecdotal but recently I've seen many "hacks" of apps built with external BaaS & auth providers that rely on some kind of token-based authentication, either via JWT or opaque tokens. What happens is that often the providers offer good support for role-based access control but developers just plain ignore it and e.g. include tokens with global read permissions into the app code, or do not properly restrict the permissions of individual tokens, making it possible to e.g. read the whole database with a normal user token. The researcher collective Zerforschung [1] e.g. has uncovered many such incidents. That might have to do with the fact that in my experience those BaaS frameworks and other low-code tools are mostly used by teams with a strong focus on product and UI/UX, which don't have deep security expertise or the right mindset. I think overall outsourcing of aspects like authentication can be beneficial, but only if teams adopt or retain a healthy security awareness as well.
I worked on an identity provider platform and this was always such a huge problem. Many application developers treat authentication as an all or nothing proposition: either a user is authenticated or they are not, but the reality is that authorization is truly hard part and often completely overlooked. This is especially true in Oauth2/OIDC schemes where JWT bearer tokens are issues. At that point you are delegating token validation and access control out to all clients. Even if you are using opaque tokens to prevent basic token verification issues, you still just end up doing the token validation for the client. They still are responsible for access controls on specific resources.
> the reality is that authorization is truly hard part
Not only is it under often estimated, but in many orgs it's also reduced to a single checkbox item on someone's go-to-market slide. ":thumbsup - we're secure now!". Instead it needs to be a constant part of the culture, in every feature from the first, and ongoing thereafter.
Out of topic, I use oidc provider (keycloak). I fetch the public key from oidc provider then verify the bearer token with it. Then use the permissions field to authorize users based on their permission. Does my approach correct / suffice?
That's the idea of the JWT, no DB query or in this case additional network request needed to authenticate.
Depending on your use case it's worth thinking about the expiration time. I assume that's checked in your client but do you also need to invalidate tokens or downgrade permissions before they expire? In that case you might want to work with smaller expiration times or get a denylist.
In general, yes that is exactly what you are supposed to do. But the really hard part is determining what scopes (which is what I assume you are referring to here as permissions) allow access to which resources/actions.
I'm always wondering what the right approach is when using third party authentication. Use scopes or just store user identifier and permission in your own database.
I have seen the two authorization approaches get co-mingled, which leads to issues.
Also, often scopes are two large.. but that's mostly an implementation choice, like read all, rather than allow access to only a specific item - maybe scopes are just less easy to handle/maintain/define for the average developer.
> I have seen the two authorization approaches get co-mingled, which leads to issues.
Correct, for me this is a must avoid at all costs. I can't imagine how hard / complex it is to manage / audit two authorization system. Unless your application need more detailed permission / smaller scope, example later.
Personally I just use the one that comes from the identity provider. In my case, keycloak's model is sufficient for my use case.
And you're right, scopes are hard and unless it's global scope, you'll need to roll your own. One good example case is github/gitlab. Global scope is the administrator access, and it's easy to set it in identity provider (as "administrator" access maybe).
However for each group / repository level, you'll need to roll your own validation.
EDIT: More often than not, it comes into business domain than technical / programming one. If you're not experienced with the business domain, no wonder you'll find it hard.
> That might have to do with the fact that in my experience those BaaS frameworks and other low-code tools are mostly used by teams with a strong focus on product and UI/UX, which don't have deep security expertise or the right mindset.
I've had the same experience. Often these are teams who experience being asked to think about access controls as a roadblock on their way to product Nirvana. Security quickly becomes something to be avoided, often right up to the point where something goes rather embarrassingly wrong.
I can tell you exactly why this happens in many companies, and it's two part.
1) These teams are usually sponsored and beholden to business instead of IT. Consequently, they care about business needs first, and good coding practices second. You can imagine how that goes, given limited project time.
2) These teams usually have poor relationships with the keepers of the IAM keys. This adversarial relationship generally takes the form of (a) IAM is asked to create an appropriate permission, (b) IAM doesn't think the way things are being done is correct and doesn't want to spend the time to correct them, (c) team just throws up their hands up and asks for a standard (overbroad) permission set.
In many places, it's easier to get an exception and admin permissions than it is to get something more specific created.
The left hand (business) saying "No one will solve this problem for us" and the right hand (IAM / security) saying "You shouldn't have to do this, so we're not going to help you" is the cause of most glaring security holes.
IMO, the rise of microservice, SPA, mobile apps or api based apps also contribute to this. It's far easier (and more easily detected / spotted) to restrict access from monolith, server side rendering based web applications.
It's far easier to enforce information Access control in a services oriented architecture.
In a monolith, a developer doesn't even have to use an access controlled API. They can simply access sensitive data through underlying access mechanisms and return it through an inappropriate endpoint.
Agree, only if you have the proper manpower, good QC and security standard in your company. For those with smaller and inexperienced team, it's easier to do it in server-render based monolith application.
I've seen a fair bit of this with Firebase apps, where devs don't write enough rules, or have collections that mix non-sensitive and sensitive fields. It's tricky, because the whole query-the-database-from-JavaScript model causes your app to fail open. I wrote a tool that acts as a generic Firebase datastore client to help find these sorts of flaws.[1]
[1] https://twitter.com/zerforschung