29 October 2026 · 7 min read · BlitzHash Team · AI & Vibe Coding

Is my AI-built app secure? Run the two-account test in 20 minutes

"Is my AI-built app secure?" is the question most founders ask right before launch, and the honest answer is: you can find out a lot in 20 minutes without reading a line of code. The fastest test is the two-account test. You create two ordinary customer accounts, put private data in one, and then try to reach it from the other. If the second account can see or change the first account's data, the app is not secure yet, however polished it looks. This guide walks you through the test step by step, with a results sheet you can fill in.

When you're done, our free launch-ready self-check helps you score the rest of the app, from secrets to backups, in the same plain-English way.

Why this one test matters so much

The most common serious flaw in web apps is not clever hacking. It is broken access control: users being able to act outside their intended permissions. OWASP, the non-profit that publishes the best-known list of web app risks, ranks broken access control at number one in its Top 10.

AI-built apps are especially prone to it. Tools like Lovable, Bolt, Cursor and Replit are very good at making screens that show *your* data when *you* are signed in. They are less reliable at making sure the database refuses to hand that data to anyone else. In apps built on Supabase, that refusal is the job of Row Level Security (RLS) rules, and one loose rule is enough to expose every customer's records.

The two-account test checks the outcome rather than the code. It doesn't matter why the data leaks. If Account B can see Account A's invoice, you have a problem to fix.

What you need

  • Two email addresses you control. Many email providers let you add +a and +b to your address (for example you+a@example.com). If yours doesn't, use two real inboxes.
  • Two separate browser sessions. A normal window and a private window, or two different browsers. They must not share cookies.
  • Your live app, or a staging copy that uses the same database rules.
  • A notes file with the results sheet below.

Do not use real customer accounts for this. Use fresh test accounts only.

The two-account test, step by step

Step 1: The empty-account check (2 minutes)

Sign up as Account B first, before creating anything. Look at every screen: dashboard, lists, search, reports, settings.

A brand-new account should see nothing but its own empty state. If B sees other people's orders, projects, messages or names, stop here. You've found a leak, usually a database rule that lets every signed-in user read every row.

Step 2: Create private data as Account A (3 minutes)

In the other window, sign up as Account A. Create one of everything your app stores: a project, an order, a message, a note, an uploaded file, a profile detail like a phone field. Use obvious test text such as "PRIVATE-A-001" so you can recognise it later.

Step 3: The URL swap (3 minutes)

As A, open each private item and copy its address from the browser bar, for example /orders/8f2c... or /projects/42. Paste each address into B's window.

  • Pass: B sees "not found", "no access", or gets sent back to their own dashboard.
  • Fail: B sees A's item, even briefly before a redirect.

A brief flash still counts as a fail. It means the data reached B's browser, and anyone can capture it from there.

Step 4: Guess the next ID (2 minutes)

If any address uses a plain number, such as /invoice/42, try /invoice/41 and /invoice/43 as B. Sequential numbers make guessing easy. OWASP's testing guide calls this insecure direct object references. Random-looking IDs help, but they are not protection on their own; the database must still refuse.

Step 5: Search, filters and exports (3 minutes)

As B, search for "PRIVATE-A". Try every filter, sort and "export to CSV" or "download" button. Search and export features are often built separately from the main screens and sometimes skip the rules the screens follow.

Step 6: Files and images (2 minutes)

As A, right-click an uploaded file or image and copy its address. Open it in B's window, and then in a window where nobody is signed in. Avatars on a public profile may be fine to share. Invoices, ID documents and contracts are not. If a private file opens for a signed-out visitor, its storage bucket is public.

Step 7: Try to change, not just see (3 minutes)

Reading is half the test. Writing is the other half. As B, open A's item address from Step 3 and look for any edit or delete button that still works. If the app shows you nothing, that's a good sign, but not proof.

If you're comfortable with your browser's developer tools, open the Network tab while A saves a change. Find the request, copy it (most browsers offer "Copy as fetch" or "Copy as cURL"), and replay it from B's session with B's sign-in. If A's record changes, the app trusts the browser to say whose data it is. Only do this on your own app and your own test accounts.

Step 8: Roles and teams (2 minutes, if you have them)

If your app has teams, admins or staff, invite B into A's team as the lowest role. Check whether B can reach the admin pages by typing their addresses directly, such as /admin or /settings/billing. Hiding a button is not the same as blocking the page. Then remove B from the team and confirm B loses access straight away, without needing to sign out.

Step 9: Sign out properly (1 minute)

As A, sign out. Press the browser's Back button and reload. Private pages should not come back. Then open a private item address in a fresh signed-out window; you should be asked to sign in.

Your results sheet

Copy this into your notes and fill it in:

| Step | What you tried | Pass / Fail | Notes (address, what you saw) | |---|---|---|---| | 1 | New account sees only its own empty state | | | | 2 | Private test data created as A | | | | 3 | A's item addresses opened as B | | | | 4 | Neighbouring IDs tried as B | | | | 5 | Search, filters, exports as B | | | | 6 | A's files opened as B and signed out | | | | 7 | Edits or deletes on A's data attempted as B | | | | 8 | Admin pages and team removal | | | | 9 | Sign-out, Back button, fresh window | | |

How to read it: any fail in Steps 1, 3, 5, 6 or 7 means customer data can leak or be changed. Don't invite more users until it's fixed. Fails in 4, 8 or 9 are serious but usually narrower.

What to do if something fails

1. Write down the exact address and screen. That's what a developer, or your AI tool, needs to fix it. 2. Check the database rules first. In Supabase-backed apps, most fails here trace back to a table with RLS off, a rule that says true, or a back door like a view or admin-powered function. Our Supabase RLS check walkthrough shows how to find each one in about 30 minutes. 3. Re-run the whole test after any fix. AI tools sometimes fix one screen and loosen another rule in the process. 4. Don't rely on hiding things in the interface. If the data reached the browser, it's exposed. The fix belongs in the database rules or server code.

It also helps to know which keys are meant to be public. The key you see in your app's code is not necessarily a leak; we explain why in is the Supabase anon key safe in the browser?. For a list that goes beyond access control, see production checks for AI-built apps.

What this test can't tell you

A clean two-account test is a strong signal, but it's not a full security review. It won't find secret keys sitting in your frontend code, payment flows that trust the browser, unprotected server functions your screens never call, or missing backups. Those need a broader check.

Practical takeaways

  • The two-account test answers "is my AI-built app secure?" for the most common serious flaw: one customer seeing another's data.
  • Always start with a brand-new empty account. If it sees anything, stop and fix.
  • Test reading and writing, screens and files, search and exports.
  • A brief flash of someone else's data is still a leak.
  • Fix the rules on the server side, then re-run the whole test.

FAQ

Can I run the two-account test if I'm not technical?

Yes. Steps 1 to 6, 8 and 9 only need a browser and two email addresses. Step 7's replay part needs the developer tools; skip it if you're unsure and note it as "not tested".

My app passed. Is it secure?

It passed the most important single test, which is good news. It can still have other problems, such as exposed secret keys or payment logic a customer can change. Run the free self-check next.

How often should I repeat it?

Before launch, after any change to sign-in, roles, teams or the database, and after any long session of asking an AI tool to fix errors.

Does Lovable or Supabase run this test for me?

Lovable's Deep scan and Supabase's Security Advisor look for many of the causes, which helps. Neither replaces using the app as two real people, because they can't know which data your business considers private.

---

Want to know where your app stands beyond this one test? Start with our free launch-ready self-check. If anything failed, our Supabase RLS check finds the rule behind it. Or book a free technical assessment, and we'll walk through your results with you and tell you what to fix first.

Sources

Related posts

Next step

Book a free technical assessment.

Thirty minutes. We look at where you are, whether you are about to build, ready to launch, or already live, and tell you what matters first. You leave with a written next step, whether or not you hire us.

Every price is a custom quote after your assessment. No work starts until you accept the proposal.