OWASP API Security Top 10

API1:2019 - Broken Object Level Authorization

Introduction to Broken Object Level Authorization

Broken Object Level Authorization (BOLA) is one of the most critical vulnerabilities in API security. This vulnerability occurs when an API request contains an identifier (such as a user ID or object ID), but the server fails to properly verify whether the requesting user is authorized to access that specific object.

This vulnerability is also commonly known as IDOR (Insecure Direct Object Reference). The term refers to situations where objects are referenced directly (usually through IDs) without proper security checks, allowing unauthorized users to access or manipulate data belonging to other users.

⚠️ Impact of BOLA Vulnerabilities

The consequences of Broken Object Level Authorization can be severe and include:

Two Types of Broken Object Level Authorization

BOLA Types Comparison
Type 1
User ID Based
(Most Common)
vs
Type 2
Object ID Based
(Resource Level)

1. User ID Based Authorization

This is the most common type encountered in bug bounty hunting. The vulnerability occurs when user identifiers are passed as parameters and the server doesn't properly validate ownership. As a hacker or security tester, you should look for parameters that contain IDs, including hidden parameters that might not be actively used but could still contain vulnerabilities.

Example: Secure Implementation (Correct)

if (getUserID() == object.ownerID) {
    showData();
} else {
    echo "You are not allowed to view this data";
    wait(5);
    redirectToHomePage();
}

Analysis: This is the proper way to handle authorization. The code first checks if the user is authorized, shows data only if authorized, and handles unauthorized access appropriately.

Example: Insecure Implementation (Vulnerable)

if (getUserID() != object.ownerID) {
    echo "You are not allowed to view this data";
    wait(5);
    redirectToHomePage();
}
showData(); // This line should never be reached, but...

Vulnerability: This implementation is dangerous because the showData() function exists after the redirect. If a user presses the back button quickly in certain browsers, the data might be displayed before the redirect completes. Always place authorized actions inside the conditional block, never after it.

2. Object ID Based Authorization

This type occurs when object IDs are passed to the server, and the server fails to properly verify authorization for those specific objects. This commonly happens when developers need to secure some resources but forget to implement authorization checks on others, especially when dealing with numerous different object identifiers.

Why This Happens

Developers often have to manage millions of different object identifiers across their application. With so many endpoints and resources to secure, it's easy to overlook certain areas. This is particularly common when developers implement security on GET methods but forget to secure POST, PUT, or DELETE methods for the same resources.

Testing HTTP Methods for BOLA

When testing for Broken Object Level Authorization, it's crucial to test all available HTTP methods, not just GET requests. Developers frequently implement authorization checks on GET endpoints but overlook other methods.

GET Method

Retrieve data - Most commonly secured, but still test thoroughly

POST Method

Create new resources - Often forgotten in authorization checks

PUT Method
PATCH Method

Update existing resources - Frequently vulnerable

DELETE Method

Remove resources - Critical if left unsecured

Example Attack Scenarios

Testing Different HTTP Methods on Product Endpoint

GET Request - Retrieve Product Details:

GET /api/v1/products/12345 HTTP/1.1

POST Request - Create New Product:

POST /api/v1/products/12345 HTTP/1.1

PUT Request - Update Product:

PUT /api/v1/products/12345 HTTP/1.1

DELETE Request - Remove Product:

DELETE /api/v1/products/12345 HTTP/1.1

OPTIONS Request - Discover Available Methods:

OPTIONS /api/v1/products/12345 HTTP/1.1

The OPTIONS method reveals all HTTP methods allowed for a specific endpoint, helping you identify additional attack vectors.

Pro Tip: Using Burp Suite

In Burp Suite Professional, you can easily transform GET requests into POST requests and test different HTTP methods. This is invaluable for thorough BOLA testing. Right-click on a request and select "Change request method" to quickly switch between GET and POST.

Detection and Prevention Strategies

How to Detect BOLA Vulnerabilities

Detecting Broken Object Level Authorization requires a deep understanding of the application's business logic. Here's a systematic approach:

BOLA Detection Workflow
Identify
All Objects
Test CRUD
Operations
Replace
Object IDs
Verify
Authorization
  1. Understand the Business Logic: Map out all objects and their relationships within the application
  2. Test All CRUD Operations: Test Create, Read, Update, and Delete actions on all objects you are NOT authorized to access
  3. Replace Object Identifiers: Systematically replace every object ID with IDs from other users (preferably your own test accounts)
  4. Test with Multiple Accounts: Create at least two test accounts and attempt to access resources across accounts
  5. Replace Authentication Headers: Swap session cookies, JWT tokens, or other authentication credentials between accounts

Automation Challenges

Automating BOLA detection is challenging because object identifiers are never defined consistently across applications. You might encounter:

  • product_id, productId, prod_id
  • invoice_id, invoiceNumber, invoice_ref
  • user_id, userId, person_id, account_id

Best Practice for Automation: Instead of trying to detect and replace all object IDs, replace the JWT token or session cookie of your logged-in user with credentials from another account you own. This approach works universally across different parameter naming conventions.

Prevention Strategies for Developers

Strategy Implementation Benefit
Use UUIDs/GUIDs Replace sequential IDs with universally unique identifiers Makes guessing valid IDs extremely difficult (but not impossible - still need authorization checks)
JWT Token Authentication Extract user ID from JWT token on the server side User ID is cryptographically signed and cannot be tampered with
Never Trust Client Input Never accept user ID as a parameter; always derive it from authenticated session Eliminates direct manipulation of user identifiers
Centralized Authorization Create a single authorization service/library used across all endpoints Ensures consistent security implementation and easier maintenance
Verify All Operations Implement authorization checks on Read, Write, Update, and Delete for every private object Comprehensive protection across all actions

Recommended Implementation Pattern

// Extract user ID from authenticated JWT token (server-side)
const authenticatedUserId = extractUserIdFromJWT(request.token);

// Fetch the requested object
const requestedObject = database.getObject(objectId);

// Verify ownership/authorization
if (requestedObject.ownerId !== authenticatedUserId) {
    return response.status(403).json({
        error: "Forbidden: You do not have access to this resource"
    });
}

// Proceed with authorized action
return response.status(200).json(requestedObject);

Key Points:

  • User ID is extracted from the JWT token, not from request parameters
  • Authorization is checked before any data is accessed or returned
  • Clear error message without revealing sensitive information
  • Return appropriate HTTP status code (403 Forbidden)

Ethical Testing Guidelines

⚠️ Critical Ethical Considerations

As a penetration tester or ethical hacker, you have strict obligations regarding data sensitivity and responsible disclosure:

Testing Best Practices:

  • Always Use Your Own Test Accounts: Never test with real user data or accounts belonging to actual users
  • Create Multiple Test Accounts: Set up at least two accounts under your control to test authorization between them
  • Avoid Production Data: When possible, test in staging or development environments
  • Document Responsibly: Record findings without exposing sensitive information

Non-Disclosure Agreement (NDA) Compliance:

  • Never Name the Target: Do not publicly disclose the name of the organization you're testing
  • Generalize Scenarios: When discussing findings, always omit specific details that could identify the target
  • Protect Sensitive Data: Never share, store, or disclose any personal data you encounter during testing
  • Limited Discussion: You can discuss vulnerabilities in general terms but never reveal exact scenarios or implementations
  • Prevent Exploitation: Ensure your reports and findings don't enable other attackers to exploit the vulnerabilities

Legal Liability:

Failure to follow ethical guidelines can result in:

  • Breach of NDA and legal action
  • Criminal charges if unauthorized access occurs
  • Civil liability for any damages resulting from your testing
  • Permanent ban from bug bounty platforms
  • Damage to your professional reputation

Example Testing Workflow

  1. Create Test Account A: Register with email [email protected]
  2. Create Test Account B: Register with email [email protected]
  3. Perform Actions as User A: Create objects, note down IDs and authentication tokens
  4. Switch to User B: Attempt to access User A's objects using User B's session
  5. Test All Methods: Try GET, POST, PUT, DELETE with User A's object IDs while authenticated as User B
  6. Document Findings: Record successful unauthorized access without exposing real data

Advanced Testing Techniques

Testing with Different Authentication Mechanisms

JWT Token Replacement

When testing APIs that use JWT (JSON Web Tokens), replace the entire token between accounts:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.USER_A_TOKEN

Replace with:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.USER_B_TOKEN

Then attempt to access User A's resources while authenticated as User B.

Session Cookie Replacement

For session-based authentication, swap cookies between accounts:

Cookie: session_id=abc123-USER-A-SESSION

Replace with:

Cookie: session_id=xyz789-USER-B-SESSION

Parameter Discovery and Testing

Look for object identifiers in various locations:

Location Example Testing Approach
URL Path /api/users/12345/profile Replace 12345 with another user's ID
Query Parameters /api/profile?user_id=12345 Change user_id parameter value
Request Body {"userId": 12345, "action": "view"} Modify userId in JSON payload
Headers X-User-Id: 12345 Change custom header values
Hidden Parameters Parameters not visible in UI Discover through proxy tools and test systematically

Common Identifier Naming Patterns

When hunting for BOLA vulnerabilities, watch for these common parameter names:

User Identifiers

user_id, userId, uid, user, account_id, person_id, customer_id

Object Identifiers

id, object_id, resource_id, item_id, entity_id

Document IDs

doc_id, document_id, file_id, invoice_id, order_id

Product IDs

product_id, prod_id, item_id, sku, catalog_id

Real-World Attack Scenarios

BOLA Attack Flow
Attacker
Authenticates
Discovers
Object IDs
Manipulates
IDs
Accesses
Victim Data

Scenario 1: Account Takeover via Profile Update

Normal Request (Updating Own Profile):

PUT /api/users/100/profile HTTP/1.1
Authorization: Bearer [User_100_Token]
{
  "email": "[email protected]",
  "password": "newpassword123"
}

Malicious Request (Attempting to Update Victim's Profile):

PUT /api/users/999/profile HTTP/1.1
Authorization: Bearer [User_100_Token]
{
  "email": "[email protected]",
  "password": "hacked123"
}

Impact: If successful, attacker can change victim's email and password, achieving full account takeover.

Scenario 2: Sensitive Data Leakage via Invoice Access

Normal Request (Accessing Own Invoice):

GET /api/invoices/12345 HTTP/1.1
Cookie: session=abc123xyz

Malicious Request (Accessing Other User's Invoice):

GET /api/invoices/12346 HTTP/1.1
Cookie: session=abc123xyz

Impact: Attacker can iterate through invoice IDs and download sensitive financial information of all users.

Scenario 3: Password Reset Token Manipulation

Normal Request (Requesting Own Password Reset):

POST /api/auth/reset-password HTTP/1.1
{
  "user_id": 100,
  "email": "[email protected]"
}

Malicious Request (Requesting Victim's Password Reset):

POST /api/auth/reset-password HTTP/1.1
{
  "user_id": 999,
  "email": "[email protected]"
}

Impact: If the API accepts the manipulated user_id and trusts the email parameter, the attacker receives a password reset link for the victim's account.

Conclusion and Key Takeaways

Why BOLA is a Critical Vulnerability

  • High Prevalence: One of the most common API vulnerabilities found in the wild
  • Severe Impact: Can lead to complete account takeover and massive data breaches
  • Easy to Exploit: Requires minimal technical skill once identified
  • Difficult to Detect: Automated scanners often miss these vulnerabilities
  • Business Logic Dependent: Requires understanding of application context

Essential Testing Checklist

  1. ✓ Test all HTTP methods (GET, POST, PUT, DELETE, PATCH) on every endpoint
  2. ✓ Use the OPTIONS method to discover available HTTP methods
  3. ✓ Replace all user IDs and object IDs with values from your second test account
  4. ✓ Test with different authentication tokens (JWT, session cookies)
  5. ✓ Look for hidden parameters in requests that might contain IDs
  6. ✓ Test both user ID based and object ID based authorization
  7. ✓ Verify that error messages don't leak sensitive information
  8. ✓ Check for authorization on read, write, update, and delete operations
  9. ✓ Test URL paths, query parameters, request bodies, and headers
  10. ✓ Always use your own test accounts - never test with real user data

Developer Security Checklist

  1. ✓ Implement centralized authorization mechanisms
  2. ✓ Extract user identity from authenticated tokens, never from parameters
  3. ✓ Use UUIDs/GUIDs instead of sequential IDs where possible
  4. ✓ Verify authorization for every CRUD operation on private objects
  5. ✓ Implement authorization checks on all HTTP methods
  6. ✓ Never trust client-supplied user IDs
  7. ✓ Use role-based access control (RBAC) or attribute-based access control (ABAC)
  8. ✓ Log all authorization failures for security monitoring
  9. ✓ Conduct regular security code reviews focusing on authorization logic
  10. ✓ Perform penetration testing with multiple user contexts

Final Thoughts for Security Researchers

Broken Object Level Authorization represents a goldmine for bug bounty hunters. There are countless undiscovered BOLA vulnerabilities in production applications today. However, success in finding these vulnerabilities requires:

Remember: When you see a user ID in a request, always change it. But make sure you're changing it to another user ID that belongs to your own test account. This simple principle, when applied consistently and ethically, can uncover serious security vulnerabilities that protect countless users from potential attacks.

Stay Secure. Test Ethically. Protect Users.

OWASP API Security - Broken Object Level Authorization Guide