// the door that looks locked

Did AI set up my login and auth correctly?

Authentication is where AI-built apps quietly go wrong: a login that looks fine but lets the wrong person in. Here is how to sanity-check yours without being a security expert.

saasreview·June 14, 2026·11 min read

To know if your app's authentication is secure, test three things: whether a logged-out visitor can reach pages or data meant for members, whether one logged-in user can load another user's records by changing an ID, and whether your password and session rules are sane. AI-built apps usually get the login form right and miss the checks behind it.

What does authentication actually protect, and what happens when it is wrong?

Authentication is the lock on the front door. It confirms a person is who they claim to be, usually with an email and password. When it is wrong, the wrong person gets in, or worse, gets in as someone else. The damage is rarely loud. There is no crash and no error page. A stranger simply sees a customer's invoices, private notes, or saved cards, and that customer never tells you, they just leave and never come back.

This matters more than it feels like when everything works in your own testing. The bug a stranger finds is the customer you never hear from again. If you are weighing whether you are ready to take payments at all, that question deserves its own look in is my app safe to charge money for yet.

What is the difference between authentication and authorization, simply?

Authentication is who you are. Authorization is what you are allowed to do. They sound like one thing, and AI tools treat them like one thing, which is exactly where apps break. A login form proves identity. It does not, by itself, stop a real logged-in user from reaching a screen or a record that belongs to someone else.

  • Authentication (authn): "Are you really alice@example.com?" Handled by the login form, password reset, magic links, OAuth.
  • Authorization (authz): "Alice is logged in, but is she allowed to open invoice #4012, which belongs to Bob?" Handled by a check you (or your AI) had to remember to write on every protected route and query.
  • The trap: Most AI scaffolds build a believable login and then assume anyone logged in can do anything. The authorization check is the part that gets skipped, because the happy path never reveals it is missing.

//The short version

A locked front door (authentication) is useless if every room inside is unlocked and unlabeled (authorization). Real attacks almost never pick the front lock. They walk in normally, then try the unlocked rooms.

What are the common auth mistakes in AI-built apps?

In apps shipped fast with AI, the same handful of gaps show up again and again. None of them look broken from the outside. Here are the ones worth checking yourself, in plain language:

  • Weak or missing password rules: the signup that silently accepts 123456, or that breaks on a 40-character password from a manager. Either way a real user hits a wall you never saw.
  • Sessions that never expire: a login that stays valid forever, on every device, even after a password change. A borrowed laptop becomes a permanent open door.
  • Missing checks on who can see what: the big one. The page loads data by ID, and nothing verifies that ID belongs to the person asking. This is called broken access control.
  • Trusting the front end: hiding an admin button with CSS while the underlying URL or API still answers anyone who types it. Hidden is not the same as protected.
  • Secrets and rules living in the browser: access decisions made in client-side JavaScript that a curious visitor can read and rewrite. Related territory in are my API keys or secrets exposed.

If you built on a hosted backend like Supabase or Firebase, the specific risk is row-level security being off or too loose. The login works perfectly, the database is wide open, and the only thing standing between users is a rule nobody wrote. "Is my Supabase auth secure" usually comes down to: are your row-level security policies actually on, and do they scope every table to the owning user.

How can I test whether a logged-out user can reach things they should not?

Test it the way a nosy stranger would, by trying to skip the front door entirely. You do not need tools for the first pass, just a second browser and a few minutes. Here is a clean walkthrough:

  1. 1.Log in as a test user and copy the URL of a private page (a dashboard, a settings page, an invoice). Note the full address.
  2. 2.Open a private or incognito window where you are logged out. Paste that exact URL and press enter.
  3. 3.What happens? You should be bounced to a login screen. If the page loads, even briefly, before redirecting, the data may already have left your server. That flash is a leak.
  4. 4.Now open your browser's network tab (right-click, Inspect, Network) on a logged-in page and watch the requests. Copy one data request URL, like /api/orders/4012, and try it logged out in a fresh tab. It should refuse you, not return JSON.

!A redirect is not the same as a block

A common AI pattern hides a page after the data already loaded. The screen redirects to login, but the protected data was sent to the browser first. If you see real content flash before the redirect, or the API returns data when you are logged out, the door is open even though the UI looks shut.

How do I check that one user cannot see another user's data?

This is the single most important test, and it is the one almost nobody runs on themselves. Create two separate accounts, then try to make one reach the other's data by changing an identifier. If it works, you have broken access control, the most common serious flaw in AI-built apps.

  1. 1.Make two test accounts: Alice and Bob. Give each one a record only they should see, like a note or an order.
  2. 2.Logged in as Alice, open one of her records. Look at the URL or the network request. You will often see something like /orders/4012 or ?id=4012.
  3. 3.Now find Bob's record id (log in as Bob in another browser, or just try 4011, 4013, nearby numbers).
  4. 4.Back as Alice, change the id in the URL or request to Bob's. Does Alice now see Bob's private record? If yes, every user can read every other user's data by guessing numbers.
$http
# Logged in as Alice, her own record returns fine:
GET /api/orders/4012   ->  200  { "customer": "alice", ... }

# Alice changes one digit to Bob's order. The dangerous answer:
GET /api/orders/4011   ->  200  { "customer": "bob", ... }   # leak

# The answer you want:
GET /api/orders/4011   ->  403  Forbidden                    # safe

That 403 (or 404) is the whole game. The server should refuse to hand Alice anything that is not hers, no matter what id she asks for. If it cheerfully returns Bob's data, the fix is a check on the server, on every query, that the requested record belongs to the logged-in user. Hiding the link is not enough, because the request still works.

Why is a self-test not enough here, and what does an outside check add?

A self-test catches the obvious gaps, but it has a built-in blind spot: you know your app too well to attack it. You instinctively use the buttons in the right order, on the right account, with valid data. You do not think to change a number in a URL, because you built it and you know which numbers are yours. The very knowledge that makes you a good builder makes you a poor attacker of your own work.

There is also a quieter trap worth naming. When something goes wrong, it is tempting to blame the user ("they did it wrong"). With authentication, that instinct points you away from the actual problem, which is almost always in the product, not the person. More on that pattern of looking past your own app in why real users break apps that worked for you.

An outside check adds the stranger's eyes you cannot supply yourself. That is the gap our Bughunt is built to fill: it is an honest, automated pass that probes your app the way a curious outsider would, finds what a nosy stranger could reach, and hands you a private, plain-English list of what to fix. It is a machine check, not a human red-team, and it stays private. We are new, so we will tell you plainly what it is rather than dress it up.

What is a reasonable first fix list if I find gaps?

If your tests turned up problems, do not panic and do not try to fix everything at once. Work top-down by blast radius. Here is a sane order:

  1. 1.Lock down cross-user data first. Add a server-side check on every record fetch: does this belong to the logged-in user? Refuse with a 403 or 404 if not. This is the highest-stakes fix.
  2. 2.Turn on row-level security if you use Supabase, Firebase, or similar, and scope every table to its owner. Confirm it is actually enforced, not just defined.
  3. 3.Stop trusting the browser. Move every access decision to the server. Hidden buttons and disabled fields are convenience, never protection.
  4. 4.Set sane session rules. Expire sessions after a reasonable time, invalidate them on password change and logout.
  5. 5.Tidy password rules. Allow long passwords, block the truly weak ones, and make sure reset flows do not leak whether an email exists.

For the bigger picture beyond login, the hub article is my AI-built app safe walks the whole surface in plain English. When you want a second set of eyes without the guesswork, you can submit your app for a Bughunt. Auth is the part that quietly costs you the most when it is wrong, which is why it is worth ten minutes with a second browser today, not after a stranger finds it first.

Want a stranger's eyes on the doors you never think to try? A Bughunt probes your app like a curious outsider and hands you a private, plain-English list of what to fix. It is an honest automated check, and it stays private.

Run a Bughunt on my app
// faq

Frequently asked questions

How do I test if my login is secure without being a developer?

Use two browsers and two test accounts. Log in as one user, copy a private page URL, then open it in a logged-out incognito window. It should bounce you to login with no data showing. Then log in as a second user and try changing an ID in the URL to reach the first user's records. If that works, you have a real gap.

Can a logged-out user access my data?

They can if your app only hides pages in the browser instead of refusing requests on the server. Test it by copying a data request URL (from the network tab) and opening it while logged out. A safe app returns a refusal like 403 Forbidden. An unsafe one returns the actual data, even though the page itself redirects to login.

What is broken access control, with an example?

Broken access control is when a logged-in user can reach data that is not theirs. The classic example: a URL like /api/orders/4012 that returns whatever order number you type, including other people's. Change 4012 to 4011 and you see someone else's order. The fix is a server-side check that the record belongs to the person asking.

Is my Supabase auth secure by default?

Not automatically. Supabase gives you a working login quickly, but your data is only protected if row-level security is turned on and every table has a policy scoping rows to their owner. A common AI-built mistake is leaving row-level security off, so the login works perfectly while the database is open to any authenticated user.

Why isn't testing my own app enough for authentication?

Because you know your app too well to attack it. You use the right buttons in the right order on your own account, so you never think to change a number in a URL or open a page logged out. That blind spot is exactly where access-control bugs hide. An outside check tries the doors you instinctively avoid.

Find the unlocked door before a stranger does

A Bughunt probes your app the way a curious outsider would and hands you a private, plain-English list of what to fix. Honest, automated, never published.

Run a Bughunt on my app
$ ls related/

Keep reading

We put every SaaS through the same honest scorecard, then publish the result.

Published on saasreview.ai · last updated June 14, 2026