The subject of Authentication (AuthN) and Authorization (AuthZ) is extremely important due to the frequency of vulnerabilities involving either of them being vulnerable. Since they seem to come up so regularly, that usually means there’s a bit of uncertainty around what they are or even just what causes them.
As a reminder, each term covers the following:
We’ll look at them separately below.
Improper authentication can cover a large variety of vulnerabilities, such as:
The first item on the list (Absence of authentication) is by far the most common issue observed in the wild. Many times, a developer will explicitly have to annotate/configure the level of authentication to be required by a page or endpoint and that step can easily be missed.
It's a good practice to ensure a system fails closed, rather than fails open. So, rather than annotating each endpoint with the information that they require an authenticated user session, the default should be that all routes require an authenticated user session unless it’s been specifically overridden. Doing this can drastically reduce the room for error.
Authorization issues can present themselves in a number of different ways that are very common:
Objects tend to have unique identifiers (IDs) that are used as a key to reference them. When a user sends a request to view an order, account, or something similar, it usually contains this ID. An "Insecure Direct Object Reference" occurs when the application fails to validate whether the user (or lack thereof) should be able to access that specific object.
Another really common vulnerability is the absence of authorization checks for a page or endpoint (as opposed to an object).
Depending on the framework used, it's common that developers have to either check for authorization in the handler or annotate the endpoint and specify the requirements needed to call the endpoint.
Unfortunately, these extra steps are also very easy to forget which often explains how some authorization vulnerabilities end up happening.
Default to closed rather than open
In the case of both Authentication and Authorization, the principle of defaulting to closed instead of open is important.
Depending on your language/framework, it’s good practice to ensure the default for all routes into your application requires an authenticated session with the highest roles or permissions possible. Doing this forces a developer to override the requirements for the route.
Enforce authorization checks in services
When accessing data, it's extremely important to ensure that all data access enforces relevant access and authorization checks in a uniform way. This is generally achieved through the use of domain service.
Below, we’ve got a short collection of examples that give a good look at the difference between secure and insecure authentication and authorization.
Missing authentication
Missing authorization
We secure software through developer-driven security at the start of the software development lifecycle.
Visit Secure Code Warrior