Skip links

Broken Object Level Authorization (BOLA) Testing

What if changing a number in a URL let someone see your customer’s private data?

Most APIs use identifiers to point at things: this account, this order, this invoice, this document. That’s just how they work. The problem shows up when the application never actually checks whether you’re allowed to look at the thing you just asked for. Change an ID from your own account to someone else’s, and if nobody’s checking ownership, you’re suddenly looking at their data instead of yours.

That’s Broken Object Level Authorization, BOLA for short, and it’s one of the most common and most dangerous access control problems in modern APIs. We test for exactly this: whether your application actually verifies that the person asking is allowed to have what they’re asking for.

What BOLA actually is

Authentication tells an application who you are. It says absolutely nothing about which specific records you’re allowed to touch. That’s a separate check, and it’s the one that gets missed constantly.

Say an API takes an order ID in a request. You’re logged in, you’re authenticated, everything checks out. But if the application never confirms that order actually belongs to you, you can just change the ID and pull up someone else’s order instead.

This can affect customer records, user profiles, orders, invoices, documents, financial records, healthcare information, messages, support tickets, and pretty much any other resource your application manages. It matters especially for APIs, because APIs tend to expose these identifiers directly, right there in the request and the response, for anyone paying attention.

Why this matters more than people expect

A login screen can be rock solid, multi-factor authentication, strong passwords, all of it, and the application can still hand over someone else’s private data the moment authentication stops being the only check that matters.

Testing for this helps you find broken object-level access controls, confirm your API authorisation actually works, validate that permissions mean what they’re supposed to mean, and catch privilege escalation before it becomes a headline. It protects sensitive records, flags insecure endpoints, and generally tightens up an area that’s easy to overlook because everything else looks fine on the surface.

How this actually happens

It comes down to a missing third question. A properly secured application needs to answer three things every time a request comes in: who’s asking, what are they asking for, and are they actually allowed to have it.

Most applications nail the first two. It’s that third check, whether this specific user is authorised for this specific object, that gets skipped or implemented sloppily. When it’s missing, you’ve got a BOLA vulnerability sitting there, waiting.

What we actually test

Object identifiers. We find every parameter and ID your application uses to reference something: user IDs, account IDs, order IDs, invoice IDs, document IDs, product IDs, ticket IDs, message IDs. Then we test what happens when we change them.

Horizontal authorisation. This is the classic case, one customer poking at another customer’s account when both have the exact same permission level. We use multiple accounts to see whether users can reach each other’s resources.

Vertical authorisation. This is the scarier version, a regular user reaching functionality meant only for admins. We check whether lower-privileged accounts can climb into territory they shouldn’t be able to touch.

API endpoints. BOLA lives most commonly in APIs, so we go through the endpoints that accept object identifiers and check whether authorisation is actually enforced, across GET, POST, PUT, PATCH, and DELETE, plus GraphQL operations where relevant.

Reading data. Can a user pull up someone else’s profile, orders, documents, transactions, messages, or personal information just by asking?

Writing and updating data. BOLA isn’t only about reading. We test whether a user can update someone else’s records, change their account information, modify their orders, or alter settings that aren’t theirs to touch.

Deleting data. Delete functionality gets tested too. Can a user delete something they don’t own or manage? This one matters a lot for business-critical information.

Multi-tenant boundaries. If you’re running a SaaS platform, cloud application, or enterprise portal, tenant separation is everything. We test whether one customer or organisation can reach into another’s resources, which would be a much bigger problem than a single leaked record.

GraphQL. GraphQL has its own version of this problem, hiding in queries, mutations, arguments, and resolver logic. We test whether object-level authorisation is actually enforced at that layer, not just assumed.

How we run the testing

Scope and planning. We start with your application’s architecture, API documentation, user roles, and authentication setup, then agree the boundaries before touching anything.

Discovery. We map the endpoints and parameters where object identifiers show up, across REST APIs, GraphQL, web applications, and mobile backends.

Setting up test accounts. Where it makes sense, we use different accounts and permission levels, so we can directly compare what one account can reach versus another.

Testing the identifiers. We manipulate object identifiers within the agreed scope to see whether that opens access to something that isn’t ours.

Validating what we find. Anything that looks like a real issue gets manually confirmed, so you’re working with facts, not maybes.

Assessing the impact. We weigh how sensitive the exposed resource actually is, a leaked support ticket and a leaked financial record are not the same conversation.

Reporting. A clear document covering the affected endpoints, the object types involved, the evidence, the risk, and how to fix it.

Retesting. Once you’ve made changes, we confirm object-level authorisation is actually working now.

What tends to turn up

Unauthorised object access. Cross-user data access. Cross-tenant data access. Unauthorised record modification or deletion. Privilege escalation. Weak API authorisation. Insecure direct object references. Missing ownership checks. Predictable identifiers that make guessing easy. Weak tenant isolation. Unauthorised GraphQL object access. Excessive permissions. Inconsistent authorisation logic across different endpoints.

BOLA vs. IDOR

These two get used almost interchangeably, and honestly, in practice, they usually describe the same underlying problem. IDOR, Insecure Direct Object Reference, is the older, broader term for exposing an object reference without properly restricting access to it. BOLA is the more specific, API-focused framing of that same idea. Either way, the actual test is the same: can someone manipulate a reference and reach something that isn’t theirs?

BOLA vs. broken function-level authorisation

Different layer, same family of problem. BOLA is about reaching an object you shouldn’t, someone else’s invoice, say. Broken function-level authorisation is about reaching a function you shouldn’t, an admin-only action, for instance. Both deserve testing, because a solid API needs to lock down both what you can touch and what you can do.

BOLA in REST APIs

REST APIs love putting identifiers right in the URL: /users/{id}, /orders/{id}, /documents/{id}, /accounts/{id}. We test whether the application actually checks that the authenticated user is authorised for that specific ID, across every method that matters, GET, POST, PUT, PATCH, DELETE.

BOLA in GraphQL APIs

GraphQL doesn’t have neat little endpoints per resource, it has queries and mutations instead. So testing shifts to object identifiers inside those queries, mutation arguments, resolver permissions, nested objects, and field-level access. Different shape, same underlying question: can you reach an object outside your authorised scope?

Who actually needs this

REST APIs, GraphQL APIs, SaaS platforms, mobile applications, customer portals, e-commerce platforms, banking and fintech applications, healthcare platforms, enterprise applications, multi-tenant applications, cloud applications, business management systems.

Basically, if your application lets users access individual records at all, orders, accounts, documents, anything, this is worth testing.

When to test

Before launching a new API or a new application. After adding new endpoints. After changing access controls or adding new user roles. After introducing multi-tenancy. After major application changes. Before a security review. Following any access control incident. As part of regular penetration testing, or as one piece of a broader API security assessment.

Testing right after a change matters most, because that’s when a missing ownership check tends to sneak in unnoticed.

What you actually get out of it

Better-protected customer data. Stronger API authorisation. Real tenant isolation instead of assumed isolation. Fewer access control blind spots. Reduced risk of sensitive data leaking out sideways. Better protection for business records. Clear visibility into privilege escalation risks. Confidence that access control changes actually did what they were meant to do.

Why work with us

We test object-level permissions the way they actually get exploited, across different users, roles, endpoints, and workflows, not just by running a scanner and hoping it catches something. That means real multi-user and multi-tenant testing, REST and GraphQL coverage, manual validation, risk-based findings, clear evidence, and practical fixes your team can act on. Once you’ve patched things, we retest to confirm it actually held.

Bottom line

A user can have a completely valid, properly authenticated account and still access someone else’s private data if object-level permissions aren’t enforced. That’s the uncomfortable truth about BOLA, it hides behind authentication that’s working perfectly fine. This kind of testing finds those gaps across APIs, web applications, mobile apps, GraphQL services, and multi-tenant platforms, before someone else finds them for you.

FAQs

What is BOLA testing?
Testing that checks whether users can access, modify, or delete objects they aren’t authorised to touch.

What does BOLA stand for?
Broken Object Level Authorization, an access control weakness where an application doesn’t properly verify whether a user is allowed to access a specific object.

Is BOLA the same as IDOR?
Closely related. Both describe accessing objects through references without proper access control. BOLA is the term more commonly used in API security discussions specifically.

Can BOLA affect REST APIs?
Yes. REST APIs commonly put object identifiers right in the URL or request, which is exactly where this testing focuses.

Can GraphQL have BOLA vulnerabilities?
Yes, through queries, mutations, arguments, nested objects, or resolver permissions that don’t properly check ownership.

Can BOLA affect multi-tenant applications?
Yes. One tenant reaching another tenant’s resources is one of the more serious versions of this problem.

Can BOLA let someone modify data, not just read it?
Yes. We test PUT, PATCH, POST, and other operations to see whether users can change resources they don’t own.

Can BOLA let someone delete data?
Potentially, yes. Delete operations get tested for the same missing ownership checks.

Do you need multiple accounts to test this?
Usually, yes. Comparing access across different accounts and roles is how we confirm whether boundaries actually hold.

Do you provide a report?
Yes. Affected endpoints and objects, testing evidence, security impact, risk information, and remediation steps.

Can you retest after fixes?
Yes. We confirm object-level authorisation is genuinely working once changes are made.

Test your APIs for Broken Object Level Authorization

Talk to Sunvak Boreal about your APIs. Let’s find out whether changing a number in a request opens a door it shouldn’t.