What BOLA actually is
Broken Object Level Authorisation (BOLA) — also known as Insecure Direct Object Reference (IDOR) in older OWASP terminology — is a class of authorisation flaw where an API endpoint grants access to a resource based on an identifier in the request, without verifying that the requesting user has permission to access that specific resource.
The mechanism is simple: User A has a valid token. User A knows (or can enumerate) the identifier for User B’s resource. The API endpoint checks that User A has a valid token but does not check that User A owns or is permitted to access the resource with that identifier. User A accesses User B’s data.
BOLA is the top OWASP API vulnerability because it is invisible to most automated scanners. A pattern-matching scanner looks for SQL injection patterns, cross-site scripting payloads, and known vulnerability signatures. BOLA does not produce an error or an unexpected response pattern — it produces a 200 OK with data that the requesting user should not have received. Only a scanner that understands the authorisation model of the specific application can detect it.
The case: paywall bypass in 31 minutes
All details below are anonymised. The customer was a B2B SaaS company (sector withheld) that had been running an annual pentest with a human firm for three years. No BOLA findings had been reported.
Scan initiated
AssurePort Web Pentest started with scope limited to production API surface. DCV verified, RoE signed.
Recon complete
47 API endpoints discovered. Tech stack: Node.js/Express, PostgreSQL, JWT auth. Paywall tier structure inferred from response schema differences between free and paid endpoints.
Auth analysis
JWT algorithm: RS256, no algorithm confusion. Sessions: stateless. Paywall enforcement: client-side tier check in frontend, separate API gate per endpoint. Gap identified: /api/reports/{id}/status endpoint missing tier check.
Exploit attempt
Free-tier token presented to /api/reports/{id}/status with a report ID belonging to a paid-tier account. Response: HTTP 200, full report content including premium fields. PoC recorded.
Validation
Second attempt with a different free-tier token and a different paid-tier report ID. Confirmed reproducible. Severity: HIGH (CVSS 3.1: 8.1).
Report delivered
Finding report available in dashboard with PoC curl command, CVSS score, and remediation recommendation. Customer notified by email.
The proof-of-concept
The PoC that arrived in the customer’s dashboard was a single curl command that any developer could reproduce in their terminal:
# Free-tier token (legitimately obtained)
TOKEN="eyJhbGciOiJSUzI1NiJ9.eyJ0aWVyIjoiZnJlZSIsInN1YiI6InVzZXJfMTIzIn0..."
# Report ID belonging to a paid-tier account (discovered via predictable ID enumeration)
REPORT_ID="rep_98765"
# BOLA exploit: free-tier token accessing paid-tier report
curl -s -H "Authorization: Bearer $TOKEN" \
https://api.[redacted].com/api/reports/$REPORT_ID/status | jq .
# Response: HTTP 200 with full paid-tier report content, including [redacted] premium fields
Why the annual pentest missed this: The human firm ran their annual test against a staging environment with synthetic data. The BOLA was only exploitable because the report IDs in production were sequential integers — a predictable pattern that the staging environment, which used UUIDs, did not reproduce. AI testing ran against the actual production surface.
The three-line fix
The remediation agent identified the specific Express route handler and generated the fix:
// Before: missing object-level authorisation check
router.get('/api/reports/:id/status', authenticate, async (req, res) => {
const report = await db.reports.findById(req.params.id);
return res.json(report);
});
// After: verify ownership before returning data
router.get('/api/reports/:id/status', authenticate, async (req, res) => {
const report = await db.reports.findById(req.params.id);
if (!report || report.userId !== req.user.id) { // line 1
return res.status(403).json({ error: 'Forbidden' }); // line 2
} // line 3
return res.json(report);
});
The customer deployed the fix within 24 hours of receiving the report. They also ran a secondary check across all 47 endpoints to identify any other instances of the same pattern — one additional endpoint was found and fixed in the same deploy.
The IDOR pattern across API designs
The paywall bypass described above is a specific variant of a broader IDOR/BOLA pattern. Common variants we encounter across web and API scans:
- Sequential integer IDs on resources that should be private (report IDs, invoice IDs, user profile IDs)
- Tenant isolation failures in multi-tenant SaaS — one tenant’s token accessing another tenant’s data
- Tier bypass via indirect endpoints — a premium endpoint is gated, but a utility endpoint that returns the same data is not
- File download IDOR — authenticated file download endpoints that check auth but not ownership
- Webhook IDOR — webhook payload endpoints that accept any authenticated request regardless of target resource ownership
Pattern-matching scanners miss all of these variants because they do not produce exploit signatures. They look like legitimate authenticated requests. Only a scanner that models the authorisation structure of the application — building a map of which users should have access to which resources — can systematically test for them. That is what the AI pentest pipeline does in the auth analysis phase.
Frequently Asked Questions
What is BOLA and why is it ranked the #1 API security risk?
Broken Object Level Authorisation (BOLA) is an access-control flaw where an API returns a resource based only on an identifier in the request, without verifying that the caller owns that resource. The OWASP API Security Top 10 (2023) lists it as API1 — the top risk — and industry analyses attribute roughly 40% of API attacks to authorisation flaws like BOLA. It ranks first because it is both extremely common and hard to detect automatically.
How is BOLA different from broken authentication?
Authentication answers “who are you?” while object-level authorisation answers “are you allowed to touch this specific record?” A BOLA endpoint authenticates the caller correctly — the token is valid — but fails to check ownership of the requested object. That is why a legitimately logged-in free-tier user could read a paid-tier report in the case above.
Why do automated scanners miss BOLA?
Pattern-matching scanners hunt for known signatures such as SQL injection strings, XSS payloads and vulnerable dependency versions. BOLA produces none of these; it returns a clean HTTP 200 with data the user should not see. Detecting it requires a scanner that models the application’s authorisation structure and actively attempts cross-account access, which is what the auth-analysis phase of an AI pentest does.
Has BOLA caused real-world breaches?
Yes. Object-level authorisation failures have exposed data at scale — from connected-car APIs leaking owner details to a T-Mobile endpoint that exposed roughly 37 million customer records in 2023. Because the flaw hides behind valid authentication, it often persists for months before discovery.
How much does it cost to test an API for BOLA with AssurePort?
API penetration tests start from $69 per scan, and the Starter plan is $69 for a single scan. Every scan runs against your real production surface, models the authorisation graph, and delivers a reproducible proof-of-concept for any BOLA finding — not just a severity label.