BOLA stands for Broken Object Level Authorization. It happens when an API correctly verifies that a request is authenticated — the user has a valid session or token — but fails to verify that the specific object being requested actually belongs to that user.
A concrete example
// Authenticated — but not authorized
app.get('/api/invoices/:id', requireAuth, async (req, res) => {
const invoice = await db.invoices.findById(req.params.id);
res.json(invoice); // never checks invoice.userId === req.user.id
});Any logged-in user can change the :id in the URL and read — or with a similar pattern on a PUT or DELETE route, modify or delete — another user’s invoice. The endpoint isn’t broken in any way a functional test would catch; it works exactly as written. It just wasn’t written to check ownership.
Wondering if your code has any of this? Scan a public repo free, no account needed.
Scan a repo →Why it’s the #1 API security issue
BOLA tops the OWASP API Security Top 10 because it’s simultaneously easy to introduce and easy to exploit. No special tooling is required to find it — an attacker just needs to change an ID and observe whether the response differs from their own data.
Why AI-generated routes are especially prone to it
AI coding tools are very good at producing the “authenticated” half of a route — adding a requireAuth middleware is a pattern models have seen constantly. The ownership check is more context-dependent: it requires knowing which field on the object maps to which field on the user, and that nuance gets dropped in fast-scaffolded CRUD endpoints far more often than the auth middleware does.
How to check for it
- Audit every route that takes an ID in the path or query string
- Confirm each one filters by the authenticated user’s ID, not just by the requested object’s ID
- Test by authenticating as one user and requesting another user’s object ID directly
- Pay closest attention to routes added quickly, or scaffolded by an AI tool, without a dedicated authorization layer