Access Control
The two-account test: the five-minute check that finds real holes.
The two-account test is the simplest way to find the most common serious flaw in your app. Create two ordinary user accounts, then try to make one reach the other's data and actions. If it works, you have broken access control. It needs no tools, just two logins and a browser.
One account can never test access control.
Everything looks secure when you use your app as one user, because you are only ever asking for your own data and you are allowed to have it. Access control is about the boundary between users, and a boundary needs two sides to test. The two-account test is how you stand on the wrong side of that boundary and see whether the app stops you.
How to run it
Create two accounts, A and B, both ordinary users, ideally in two different browsers or a normal and a private window so you stay logged into both. Populate A with something real: an order, a document, a message, a profile detail. Note the URLs and, if you can see them, the IDs of A's items.
Now become B and try to reach A's things directly. Paste A's URL while logged in as B. Change an ID in one of B's own requests to point at A's record. Try to open, edit or delete A's item through any route you can find. You are doing exactly what an attacker does: asking for data that is not yours and seeing if the server hands it over.
What the results mean
If B is refused every time, with a not-found or not-authorised response, that path enforces access control correctly. If B sees, edits or deletes A's data, you have found a live hole, and specifically an insecure direct object reference or a missing ownership check. That is not a theoretical risk; it is a stranger reading your users' data, reproduced on demand.
Test each kind of record that carries weight: anything with personal information, money, private content or account control. A single unprotected endpoint is enough to matter, so the goal is coverage, not a single pass.
Extend it for more coverage
Add a third dimension by testing as no user at all: log out entirely and try to reach A's data with the public key or a bare request. Add a fourth by making B an ordinary user and trying to reach admin-only functions. These variations catch unauthenticated exposure and privilege escalation, the other common forms of broken access control, using the same simple idea.
The two-account test is deliberately something you can run yourself, today, and we encourage it. What it cannot do is guarantee coverage of every endpoint and every table in a real app, or catch the subtler cases. That systematic version, run across your whole surface with the edge cases included, is what our security audit provides.
Common questions.
- Do I need special tools to run the two-account test?
- No. Two accounts and a browser are enough for the core test. Editing a request to change an ID can be done in the browser's dev tools. The whole point is that the most revealing access-control check needs no tooling at all.
- What if I find a hole?
- It means an endpoint is not checking ownership before returning or changing data. The fix is to enforce that check on the server, and on Supabase or Firebase to enforce it in row-level security or security rules. If you want the full set found and fixed, that is our security audit.
- Does passing the two-account test mean my app is secure?
- It means the paths you tested enforce access control, which is a genuinely good sign. It does not cover every endpoint, unauthenticated exposure, or subtler flaws. Treat a pass as encouraging, not as a clean bill of health.
Related services.
Let's build something real.
Tell us about your app or idea. You'll get a clear plan and a fixed quote back within 24 hours.
