GUIDE 04 · WEB APPLICATIONS AND APIs
IDOR and BOLA: test access to another user’s data
An identifier is not an authorization decision. To test object access, use two accounts, known private objects and explicit expected permissions. Confirm that each owner can use its own object and that another identity cannot retrieve the private content, including through exports or downloads.
Check user isolationSign-in, ownership verification and consent are required. Authorized scenarios, monitoring and CI require Pro or Business.
On this page
Understand IDOR and BOLA
IDOR describes unsafe direct object references; BOLA describes broken object-level authorization in an API. A readable ID is not itself the vulnerability. The issue is a server returning or modifying an object without enforcing the caller’s ownership, organization and role rules.
Prepare two independent contexts
Create A in organization X and B in organization Y, with separate sessions and synthetic documents. Record document paths and unique private markers. First prove that A can read A and B can read B. Otherwise, a forbidden cross-user request could simply reflect invalid sessions or unavailable fixtures.
Primary sources: Primary reference 1 · Primary reference 2
Test reads step by step
Request B’s known document using A’s session, then reverse the direction. Inspect private content as well as status. Our controlled fixture returns the other owner’s marker in its vulnerable mode; the fixed mode returns 403 while both owners retain access. The actual BOLA rule confirms the vulnerable observation with repeated reads.
| Identity | Object | Method | Fixed fixture expectation |
|---|---|---|---|
| A | doc-a | GET | 200 |
| A | doc-b | GET | 403 |
| B | doc-b | GET | 200 |
| B | doc-a | GET | 403 |
| guest | doc-a | GET | 200 |
| guest | doc-b | GET | 403 |
| anonymous | doc-a | GET | 401 |
| A | doc-b/download | GET | 403 |
| B | doc-a/download | GET | 403 |
| A | doc-a/download | GET | 200 |
| B | doc-b/download | GET | 200 |
| anonymous | doc-b/download | GET | 401 |
Check alternate paths to the same object
A protected detail endpoint does not prove that exports, previews and downloads enforce the same permissions. Repeat the known-object test on relevant supported paths. Include guest and anonymous contexts where they have defined permissions. Do not interpret a public resource as private without an explicit expectation.
python3 access-fixture.py
curl -H "X-Fixture-User: a" "http://127.0.0.1:8769/documents/doc-b?mode=vulnerable"
curl -H "X-Fixture-User: a" "http://127.0.0.1:8769/documents/doc-b?mode=fixed"Primary sources: Primary reference 1 · Primary reference 2
Continue: Supabase security: check RLS and access to data
Check user isolationTest changes and protected fields
Changing a role, owner or tenant can be more consequential than a read. Define an approved staging mutation, the expected forbidden fields and a way to verify restoration. Do not infer update safety from read controls, and do not perform write checks on production customer objects.
Enforce permissions on the server
Derive identity from a verified session, load trusted object ownership and apply the application’s organization and role rules before returning data or writing changes. A hidden button or client-side condition cannot replace this check. Keep authorization consistent across the main endpoint and secondary access paths.
Primary sources: Primary reference 1 · Primary reference 2
Continue: JWT security: validate tokens and access lifecycle
Prove the fix
The original cross-owner attempt must stop exposing private content, but each owner must still access its own object. A redirect to login, timeout or WAF block is not sufficient proof. Keep the same fixture contract, environment and deployment identifier so the retest compares the intended behavior.
Automate the regression check
Save supported access scenarios in Scantelio and rerun them after releases. Use a targeted retest for a known finding and a broader release check for the rest of the approved coverage. Review the report when roles, organizations, object paths or fixture markers change.
Reproducible examples and downloads
All example data is synthetic. Downloads contain no active keys or customer records. Run examples only in your own isolated test environment.
Example verification record: versions, actions and observations

Questions and answers
Are UUIDs enough to prevent IDOR?
No. Hard-to-guess IDs reduce discoverability but do not enforce permissions.
Does a 403 prove the entire API is safe?
It proves only that response under those conditions. Verify legitimate controls and relevant alternate routes.
Can tenant isolation be tested?
Yes, with independent tenant identities, known fixtures and explicit expected denial.
Must every cross-user request fail?
No. Some resources are intentionally shared. Expected access must reflect the product’s rules.
Can downloads leak an otherwise protected object?
Yes. Test the known object through relevant export and download paths too.
What should an inconclusive retest mean?
The available evidence cannot establish whether the issue was fixed; do not label it resolved.
Editorial team and sources
Scantelio editorial team: methodology and limitations. Example verified: 2026-11-02.
Apply the check to your own project
Check user isolationChoose your project after signing in. No scan runs without verification and consent.
