Safeguard
Security Guides•

BOLA in banking APIs: checking the account ID on every call

Broken object level authorization lets a logged-in user read or move another customer's account by changing an ID. How it shows up in banking APIs and the fix.

Safeguard Security Team
4 min read

Broken object level authorization (BOLA) happens when an API accepts an account, card or payment ID from the client and never checks that the logged-in user may touch that record. In banking APIs the stakes are high: one changed ID in a path can expose another customer's balance, statement or payment.

What it looks like in a payments API

Take an endpoint such as a statement download that accepts an account ID in the path. The caller is authenticated and allowed to use the endpoint. The flaw is that nobody asks whether this account belongs to this caller.

OWASP ranks this class first in its 2023 API Security Top 10. It notes that attackers change object IDs in paths, query strings, headers or payloads, and that the impact can range from data disclosure to data loss and, in some cases, full account takeover.

Banking adds its own versions of the same bug:

  • A beneficiary ID that belongs to another customer.
  • A card ID used to change limits or freeze a card.
  • A payment ID used to read or cancel a scheduled transfer.
  • A consent ID in an open banking flow used to read data the user never shared.

Why authentication does not stop it

Authentication proves who the caller is. Object level authorization decides what that caller can reach. A valid token with a valid session still fails this test if the server trusts the ID in the request.

Hiding IDs does not fix it either. OWASP suggests random, unpredictable IDs as a defense in depth, but says the real control is the authorization check. A guessable ID makes the bug easier to exploit. An unguessable one only makes it harder to find, and IDs leak through logs, emails and shared links.

A fix that holds up

  1. Resolve the object through the caller. Instead of loading an account by ID and then checking, load it by ID and owner together. A lookup that returns nothing for a foreign ID fails closed.
  2. Check on every function that uses client input to reach a record. Reads, updates, deletes and exports all count.
  3. Centralise the policy. One authorization layer or helper is easier to review than a check pasted into each handler.
  4. Use random IDs as a second layer, not the first.
  5. Return the same error for missing and forbidden objects where that is acceptable, so attackers cannot map which IDs exist.

Test for it

Write authorization tests with two users. User A creates an account, card and payment. User B then tries each endpoint with A's IDs and must get a denial every time. Run these tests in CI and block merges that break them, as OWASP advises.

Also test background paths: webhooks, batch exports and admin tools often skip the checks that the main API enforces.

Try it yourself

Click through it at your own pace, or open it full screen.

Click through the scan and look at how API findings are grouped by endpoint, since authorization gaps rarely sit in one place.

Safeguard offers API security scanning as part of its GA scanner set, and you can start with the free scan at https://gold.safeguard.sh/scan. Scanners help find candidates, but a two-user authorization test remains the best proof.

Quick check

Do random account IDs fix BOLA?

No. They make guessing harder, but IDs leak. The fix is a server side check that the caller owns the object.

Is BOLA the same as missing authentication?

No. The caller is authenticated. The missing piece is the per-object permission check.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.