Post Page Advertisement [Top]



Click here to send WhatsApp On Unsaved Mobile Numbers For Free

 

Ethical Hacking Broken Access Control, IDOR & BOLA — Authorization Testing Lab | Day 23
Ethical Hacking

🛡️ Ethical Hacking — Day 23

Broken Access Control, IDOR & BOLA — Authorization Testing Lab

⚠️ LEARNING PURPOSE ONLY: This tutorial is strictly for educational and defensive cybersecurity learning. Perform every practical exercise only against your local OWASP Juice Shop lab, applications you own, or systems for which you have explicit authorization. Never access another person's data or modify permissions on systems without explicit authorization.

Welcome to Day 23.

Yesterday we learned:

  • Authentication

  • Sessions

  • Cookies

  • Login security

  • MFA

  • Password reset

  • Session invalidation

Today we move to one of the most important concepts in web application security:

🔐 Authorization

Authentication asks:

Who are you?

Authorization asks:

What are you allowed to access or perform?

A user can be correctly authenticated and still be able to access something they shouldn't.


🎯 Today's Learning Objectives

You'll learn:

  • Authentication vs authorization

  • Broken Access Control

  • IDOR

  • BOLA

  • Horizontal privilege escalation

  • Vertical privilege escalation

  • Object-level authorization

  • Function-level authorization

  • API authorization

  • Role-based access control

  • Ownership checks

  • Burp Repeater testing

  • Safe authorization testing

  • Laravel authorization

  • Spring Security authorization

  • Linux practical commands

  • Windows PowerShell practical commands

  • macOS practical commands

  • How to write an access-control finding


1. Authentication vs Authorization

Remember:

AUTHENTICATION
      ↓
"Who are you?"
      ↓
Identity

versus:

AUTHORIZATION
      ↓
"What can you do?"
      ↓
Permissions

Example:

User A
   ↓
Authenticated ✓
   ↓
GET /profile
   ↓
Allowed ✓

But:

User A
   ↓
Authenticated ✓
   ↓
GET /admin/users
   ↓
Should be denied ✗

2. What Is Broken Access Control?

Broken access control occurs when an application fails to properly enforce what an authenticated user is allowed to access or perform.

Conceptually:

User
 ↓
Authentication ✓
 ↓
Authorization check
 ↓
❌ Missing / Incorrect
 ↓
Protected resource

The security problem isn't necessarily the login system.

The problem is the permission decision.


3. Real-World Example

Imagine:

GET /api/users/100

User 100 owns that record.

User 101 logs in and requests:

GET /api/users/100

If the server simply checks:

"Is the requester logged in?"

instead of:

"Is the requester allowed to access user 100?"

there may be an authorization vulnerability.


4. IDOR

IDOR means:

Insecure Direct Object Reference

It traditionally refers to situations where an application exposes an object reference such as:

/users/100
/orders/500
/invoices/200
/documents/15

and fails to verify whether the current user is authorized to access that object.

Modern OWASP terminology often discusses this under Broken Access Control and BOLA — Broken Object Level Authorization.


5. BOLA

BOLA is particularly relevant to APIs.

Example:

GET /api/orders/100

The server receives:

Object ID = 100

It must determine:

Is the authenticated user allowed to access order 100?

Not merely:

Is the user authenticated?

6. Authorization Decision

A secure authorization decision resembles:

Authenticated User
        │
        ▼
     Request
        │
        ▼
 Resource = Order 100
        │
        ▼
 Ownership / Permission Check
        │
    ┌───┴───┐
    ▼       ▼
  ALLOW    DENY

7. Horizontal Privilege Escalation

Horizontal escalation means:

A user accesses another user's resources at approximately the same privilege level.

Example:

User A
 ↓
Own Profile
 ↓
/users/101

Then attempts:

/users/102

If user 101 can access user 102's private information without authorization, that's a potential horizontal access-control issue.


8. Vertical Privilege Escalation

Vertical escalation means:

A lower-privileged user accesses functionality intended for a higher-privileged role.

Example:

Normal User
     ↓
/admin/users

If the server allows it:

User
 ↓
Admin Function

that's a serious authorization problem.


9. Example Role Model

Imagine:

ADMIN
 ├── Manage users
 ├── Manage products
 ├── View reports
 └── Configure system

MANAGER
 ├── Manage assigned products
 └── View reports

USER
 ├── View own profile
 └── Create own orders

The server must enforce these rules.


10. Never Trust the UI

Suppose the UI hides:

Delete User

from normal users.

That doesn't provide real security.

An attacker may still manually send:

DELETE /api/users/100

Therefore:

Authorization must be enforced server-side.


11. Start Your Lab

Linux

docker ps

Windows PowerShell

docker ps

macOS

docker ps

Verify:

Linux/macOS

curl -I http://127.0.0.1:3000

Windows

curl.exe -I http://127.0.0.1:3000

12. Start Burp Suite

Open:

Burp Suite
   ↓
Proxy
   ↓
Open Browser

Navigate to:

http://127.0.0.1:3000

Keep your testing scope limited to:

127.0.0.1:3000

🧪 Practical Lab 1 — Find Object References

After logging into your local Juice Shop account, browse normally.

Open:

Proxy
 ↓
HTTP history

Look for requests containing:

/users/
/orders/
/products/
/reviews/

or JSON fields such as:

{
  "id": 123
}

Don't assume a particular endpoint exists. Analyze the requests generated by your local application.


13. Build an API Map

Create:

Feature          Endpoint              Object ID
-------------------------------------------------
Profile          _____________         _____
Order            _____________         _____
Product          _____________         _____
Review           _____________         _____
Other            _____________         _____

You're learning to recognize object references.


14. Send a Request to Repeater

Choose a request involving your own test data.

Right-click:

Send to Repeater

Then:

Repeater
 ↓
Send

Record the baseline:

Status:
Response size:
Object:
Authenticated user:

15. Don't Attack Random IDs

For today's exercise, don't blindly enumerate:

1
2
3
4
5
...
10000

Instead, use:

Your own test account
Your own test objects
Known local lab data

The purpose is to understand authorization—not to collect other users' information.


16. Safe Object Authorization Test

Suppose your own account owns:

Order 100

Your baseline:

GET /orders/100

returns:

200 OK

Now, only if your local lab contains another deliberately created test account/object, compare behavior using that controlled object.

For example:

GET /orders/101

Observe whether the application returns:

403 Forbidden

or:

404 Not Found

or another appropriate denial.

Don't modify or access data belonging to real users.


17. Why 403 vs 404?

An application might return:

403 Forbidden

meaning:

You are authenticated, but not allowed.

Or:

404 Not Found

to avoid revealing whether the object exists.

Both can be valid design choices depending on the application's security and information-disclosure requirements.


18. What Would Be a Finding?

Imagine:

User A
 ↓
Own object: 100
 ↓
GET /objects/100
 ↓
200 OK

Then:

User A
 ↓
Object belonging to User B: 101
 ↓
GET /objects/101
 ↓
200 OK

and the server returns User B's private information.

That is a strong indication of a BOLA/IDOR-style authorization issue.


19. Important Distinction

Don't conclude:

Different ID
+
200 OK
=
IDOR

You need to establish:

Who owns the object?
Who is requesting it?
What should the requester be allowed to do?
What data was returned?

Evidence matters.


20. Horizontal Testing

Use two local lab accounts if your environment supports it.

Conceptually:

Account A
   ↓
Object A

and:

Account B
   ↓
Object B

Test:

Account A → Object A → Expected ALLOW
Account A → Object B → Expected DENY
Account B → Object B → Expected ALLOW
Account B → Object A → Expected DENY

This is one of the cleanest ways to understand object-level authorization.


21. Authorization Matrix

Create:

RequesterObjectExpectedActual
User AObject AAllow___
User AObject BDeny___
User BObject ADeny___
User BObject BAllow___

This is far better than random testing.


22. Vertical Testing

Now think about roles.

Create a conceptual matrix:

RoleNormal FunctionManager FunctionAdmin Function
User✓✗✗
Manager✓✓✗
Admin✓✓✓

The server must enforce this matrix.


23. UI vs Server

Suppose a normal user doesn't see:

Admin Dashboard

You should still ask:

Does the server enforce the restriction?

Because:

Hidden button
     ≠
Authorization

24. Function-Level Authorization

Authorization isn't only about objects.

It also applies to functions.

Examples:

POST /users
DELETE /users/10
PUT /settings
POST /admin/reports

The server should determine:

Can this user perform this action?

25. HTTP Methods Matter

A resource might support:

GET
POST
PUT
PATCH
DELETE

Authorization may differ by operation.

Example:

GET /profile
→ allowed

PUT /profile
→ allowed

DELETE /profile
→ restricted

Never assume:

"If I can read it, I can modify it."


26. API Authorization

For APIs, think:

Identity
   +
Object
   +
Action
   +
Role
   +
Ownership

For example:

User A
wants to
DELETE
Order 100

The server should check:

Is User A allowed to DELETE Order 100?

27. Broken Function-Level Authorization

Example:

Normal user:
POST /api/profile

allowed.

But:

Normal user:
POST /api/admin/create-user

should be denied.

If the application checks only authentication:

Logged in? YES

instead of authorization:

Admin? NO

there may be a vulnerability.


28. Laravel Authorization

Laravel provides mechanisms such as:

Gates
Policies
Middleware

Conceptually:

$this->authorize('update', $post);

The important principle:

Request
 ↓
Authenticated User
 ↓
Policy Check
 ↓
Allow / Deny

Don't rely only on hiding UI elements.


29. Laravel Policy Example

Conceptually:

public function update(User $user, Post $post): bool
{
    return $user->id === $post->user_id;
}

This implements an ownership rule:

Current User
      =
Post Owner

Then:

ALLOW

otherwise:

DENY

30. Spring Security

Spring Security supports authorization using:

Roles
Authorities
Method Security
Request Authorization

For example:

@PreAuthorize("hasRole('ADMIN')")

This can protect an administrative operation.

But object-level authorization may still require an ownership check.


31. Role Check Isn't Always Enough

Consider:

ROLE_USER

Both User A and User B have the same role.

A role check alone cannot determine:

Does User A own Object B?

You may need:

Role
+
Ownership

32. Ownership Check

Secure logic:

Current User
      │
      ▼
Object requested
      │
      ▼
Object.owner_id
      │
      ▼
Compare IDs
      │
   ┌──┴──┐
   ▼     ▼
 Match  No Match
   │       │
 ALLOW    DENY

33. Don't Trust User-Supplied Owner IDs

A dangerous design might accept:

{
  "owner_id": 100
}

and simply trust it.

The server should derive ownership from the authenticated identity where appropriate.

Conceptually:

Authenticated User ID
        ↓
Server-side ownership

rather than:

Client-supplied owner_id
        ↓
Trust

34. Mass Assignment Connection

This connects to another vulnerability class.

Imagine:

{
  "name": "Rohit",
  "role": "admin"
}

If a normal user can submit:

role = admin

and the application blindly updates it, there may be a serious authorization issue.

Frameworks provide mechanisms to restrict which fields users can modify.


35. Safe API Design

Instead of trusting:

{
  "user_id": 123,
  "role": "admin"
}

the server should determine:

Current authenticated identity
+
Allowed fields
+
Server-side authorization

36. Linux Practical Session

Check your lab:

docker ps

Inspect headers:

curl -I http://127.0.0.1:3000

Verbose request:

curl -v http://127.0.0.1:3000/

Through Burp:

curl -x http://127.0.0.1:8080 \
http://127.0.0.1:3000/

37. Linux — Save a Response

For your local lab:

curl -s http://127.0.0.1:3000/ > day23.html

Search for an object identifier:

grep -n "123" day23.html

Replace 123 with an identifier relevant to your own lab data.


38. Windows Practical Session

Check:

docker ps

Headers:

curl.exe -I http://127.0.0.1:3000

Verbose:

curl.exe -v http://127.0.0.1:3000/

Through Burp:

curl.exe -x http://127.0.0.1:8080 `
http://127.0.0.1:3000/

39. Windows — Search Local Response

curl.exe -s http://127.0.0.1:3000/ -o day23.html

Then:

Select-String -Path day23.html -Pattern "123"

Replace 123 with a relevant test object ID.


40. macOS Practical Session

docker ps
curl -I http://127.0.0.1:3000
curl -v http://127.0.0.1:3000/

Through Burp:

curl -x http://127.0.0.1:8080 \
http://127.0.0.1:3000/

41. macOS — Search

curl -s http://127.0.0.1:3000/ > day23.html

Then:

grep -n "123" day23.html

Again, replace the example identifier with one from your own lab.


42. Burp Repeater Authorization Workflow

Use:

Capture request
      ↓
Send to Repeater
      ↓
Baseline
      ↓
Identify object/action
      ↓
Controlled authorization comparison
      ↓
Compare response
      ↓
Document

Do not automate large-scale enumeration.


43. Response Comparison

Create:

RequestStatusSizeData ReturnedExpected
Own object_________Allow
Other test object_________Deny
Admin function_________Deny
Own update_________Allow

This makes your conclusions evidence-based.


44. BOLA Testing Questions

For each API endpoint ask:

Identity

Who is making this request?

Object

Which object is being accessed?

Action

What operation is being performed?

Ownership

Does the user own this object?

Role

Does the user's role allow this action?

Result

Did the server enforce the rule?

45. Authorization Checklist

Review:

☐ Authentication is required
☐ Authorization checked server-side
☐ Object ownership checked
☐ Role checked
☐ Function permissions checked
☐ Read access controlled
☐ Write access controlled
☐ Delete access controlled
☐ API endpoints protected
☐ Hidden UI isn't treated as security
☐ User-supplied IDs aren't blindly trusted
☐ Sensitive operations require appropriate privileges

46. Common Access-Control Mistakes

Mistake 1

if user is logged in:
    allow()

Too broad.

Better

if authenticated
and authorized_for_resource:
    allow()
else:
    deny()

47. Common Mistake — Client-Side Authorization

Bad design:

if (user.role === "admin") {
    showDeleteButton();
}

This may control the UI, but the server still needs to enforce:

DELETE /users/100

authorization.


48. Common Mistake — Predictable IDs

Sequential IDs:

100
101
102
103

aren't automatically a vulnerability.

The real issue is:

Predictable ID
+
Missing authorization
=
Potential access-control vulnerability

Random IDs alone don't replace authorization checks.


49. Common Mistake — "It's an Internal API"

Never assume:

/internal/api

is automatically secure.

If an attacker can reach the endpoint, the server must enforce authorization.


50. Common Mistake — Frontend Trust

Never trust:

role=admin

sent by the browser.

Never trust:

user_id=123

simply because it came from your frontend.

Never trust:

is_admin=true

from client-controlled input.

Security decisions should be made server-side using trusted identity and authorization data.


51. Day 23 Main Lab

Perform a controlled authorization assessment.

Step 1

Create or identify:

User A
User B

using only your local lab.

Step 2

Create:

Object A
Object B

where possible.

Step 3

Capture:

User A → Object A

Step 4

Record the baseline.

Step 5

Authenticate as User B.

Step 6

Test the same type of request against your controlled test objects.

Step 7

Build:

User A → Object A → Expected Allow
User A → Object B → Expected Deny

User B → Object B → Expected Allow
User B → Object A → Expected Deny

Step 8

Check a privileged function if your lab provides one.

Step 9

Document the results.


📊 Day 23 Authorization Matrix

Fill this out:

╔════════════════════════════════════════════╗
║       DAY 23 ACCESS CONTROL MATRIX        ║
╚════════════════════════════════════════════╝

              Object A    Object B
User A           ✓          ✗
User B           ✗          ✓

Expected:

User A → Object A: ALLOW
User A → Object B: DENY

User B → Object A: DENY
User B → Object B: ALLOW

Actual:

User A → Object A: __________
User A → Object B: __________

User B → Object A: __________
User B → Object B: __________

🧪 Day 23 Security Report

╔══════════════════════════════════════╗
║   DAY 23 — ACCESS CONTROL REPORT     ║
╚══════════════════════════════════════╝

Target:
127.0.0.1:3000

Feature:
________________________

Endpoint:
________________________

HTTP Method:
________________________

Requester:
________________________

Object:
________________________

Object Owner:
________________________

Expected Authorization:
________________________

Actual Authorization:
________________________

HTTP Status:
________________________

Data Returned:
________________________

Horizontal Escalation:
Yes / No / Unknown

Vertical Escalation:
Yes / No / Unknown

BOLA / IDOR:
Yes / No / Unknown

Evidence:
________________________

Impact:
________________________

Recommended Fix:
________________________

📝 Day 23 Assignment

Answer these questions:

  1. What is authorization?

  2. How is authorization different from authentication?

  3. What is Broken Access Control?

  4. What is IDOR?

  5. What is BOLA?

  6. What is horizontal privilege escalation?

  7. What is vertical privilege escalation?

  8. What is object-level authorization?

  9. What is function-level authorization?

  10. Why isn't hiding a button sufficient security?

  11. Why shouldn't the server blindly trust user_id from the client?

  12. Why isn't a predictable ID automatically an IDOR?

  13. Why should authorization be enforced server-side?

  14. Why might an application return 404 instead of 403?

  15. Why does a role check alone sometimes fail to protect an object?

  16. What is an ownership check?

  17. How can Laravel Policies help?

  18. How can Spring Security help?

  19. What is the difference between read and write authorization?

  20. What information should an access-control security report contain?


🏆 Day 23 Challenge

Create this diagram:

                 AUTHENTICATED USER
                         │
                         ▼
                    API REQUEST
                         │
               ┌─────────┴─────────┐
               │                   │
            OBJECT              ACTION
               │                   │
               └─────────┬─────────┘
                         ▼
                AUTHORIZATION CHECK
                         │
              ┌──────────┼──────────┐
              │          │          │
              ▼          ▼          ▼
          Ownership     Role     Permission
              │          │          │
              └──────────┼──────────┘
                         ▼
                  ┌──────┴──────┐
                  ▼             ▼
                ALLOW          DENY

Then add:

Authentication
Session
Audit Logging
Rate Limiting

🔐 Day 23 Golden Rules

Rule 1

Authentication tells you who the user is; authorization determines what they can do.

Rule 2

Never rely on the frontend for security decisions.

Rule 3

Every protected object requires an authorization decision.

Rule 4

A valid user session does not mean access to every resource.

Rule 5

Predictable IDs aren't the vulnerability; missing authorization is.

Rule 6

Test authorization with controlled accounts and objects only.


📚 Day 23 Summary

Today you learned:

  • Authentication vs authorization

  • Broken Access Control

  • IDOR

  • BOLA

  • Horizontal privilege escalation

  • Vertical privilege escalation

  • Object-level authorization

  • Function-level authorization

  • API authorization

  • Ownership checks

  • Role-based authorization

  • Laravel Policies

  • Spring Security

  • Burp Repeater

  • Authorization matrices

  • Linux commands

  • Windows PowerShell

  • macOS

  • Security reporting

🔑 Most Important Lesson

Don't ask only:

"Can this user log in?"

Ask:

"Is this specific user allowed to perform this specific action on this specific resource?"

That question is at the heart of access-control security.


🔜 Day 24 — IDOR/BOLA Practical API Lab

Tomorrow we'll go deeper into:

  • API object references

  • BOLA testing methodology

  • Request/response comparison

  • Ownership validation

  • GET vs POST vs PUT vs DELETE authorization

  • API role checks

  • Burp Repeater

  • Laravel API authorization

  • Spring Security API authorization

  • Safe two-account lab testing

  • Linux, Windows & macOS practical sessions

  • Professional BOLA/IDOR reporting

⚠️ LEARNING PURPOSE ONLY: All exercises remain restricted to your local/authorized environment. Never access or modify another person's data.

No comments:

Post a Comment

Bottom Ad [Post Page]

rrkksinha.