Intermediate

What Is Authorization

15 min 4 sections
1

Introduction

Authentication vs Authorization

i

Introduction

Authentication and authorization answer two separate questions, and conflating them is where many access-control vulnerabilities begin.

Authentication asks: Who are you?

It establishes the identity of the requester using something such as a password, OTP, passkey, or valid session credential.

Authorization asks: What is that authenticated identity allowed to do?

Once the application knows who the requester is, it must determine whether that identity has permission to access the specific resource or perform the specific action being requested.

A simple flow looks like this:

Request
   ↓
Authentication
"Who is this?"
   ↓
Authenticated identity
   ↓
Authorization
"What may this identity do?"
   ↓
Allow / Deny

The critical point is that successful authentication does not imply authorization.

If the application only checks whether the user has a valid session and never checks their permissions, the authentication system can be perfectly secure while the authorization system is completely broken.

An attacker doesn't need to steal another user's password. They simply authenticate as themselves and request something they should never have access to.

Authentication: ✓
"I am user123."

Authorization: ✗
"user123 is allowed to access /admin."

This is why authorization must be enforced at the point where the protected resource or action is accessed, not assumed merely because the user successfully logged in earlier.

Authentication establishes identity. Authorization determines permissions.

2

Concept

Horizontal Authorization

Horizontal authorization governs whether one user can access resources belonging to another user at the same privilege level. A user may be fully authenticated and legitimately authorized to access their own order, but that does not mean they are authorized to access every order.

For example:

GET /orders/4521   → belongs to the logged-in user
GET /orders/4522   → belongs to a different user

If changing the order ID causes the second request to return another user's order, the application has a horizontal authorization failure — commonly called IDOR (Insecure Direct Object Reference), or BOLA in API security terminology.

The authentication check succeeded:

User is logged in ✓

But the object-level authorization check was missing:

Does order 4522 belong to this user? ✗

The fundamental mistake is checking whether the requester is authenticated without checking whether they are authorized to access the specific object they requested.

3

Concept

Vertical Authorization

Vertical authorization governs access across privilege levels — for example, whether a standard user can perform an action reserved for an administrator.

A common failure is implementing the restriction only in the interface. The application hides the admin functionality from ordinary users, but the underlying endpoint never independently verifies the caller's privileges.

For example:

POST /admin/delete-user
        ↓
Request sent directly by standard user
        ↓
Server checks authentication ✓
Server checks admin privilege ✗
        ↓
User deleted

The attacker doesn't need to see an "Admin" button. They can discover or guess the endpoint and call it directly:

POST /admin/delete-user

If the request succeeds while authenticated as a standard user, the application has a vertical authorization failure.

Hiding an admin link, disabling a button, or restricting navigation with JavaScript provides no security boundary. The server must independently enforce the required privilege on every request to the protected functionality.

4

Concept

Resource Ownership

Resource ownership is the principle that makes horizontal authorization work. A role check only answers:

"What kind of user is this?"

It does not answer:

"Is this user allowed to access this particular resource?"

Suppose the application allows users to edit their own profiles:

PATCH /profile/8831   → request from user 8831 → allowed
PATCH /profile/8831   → request from user 9042 → rejected

Both requests may come from perfectly authenticated users with exactly the same role:

User 8831 → role = user ✓
User 9042 → role = user ✓

The authorization decision must therefore go one step further and check the relationship between the authenticated user and the requested resource:

Authenticated user
        ↓
What resource are they requesting?
        ↓
Does this user own / have permission for that resource?
        ↓
Allow or deny

Without that second check, an application can have a perfectly functioning role system while still allowing users to access one another's data.

You've completed Authorization and Access Control

Great work — explore other topics to keep learning.