Authentication is the feature where mistakes hurt the most, because it guards everything behind it. It is also the feature AI tools are most confident about and most likely to get subtly wrong, since a login that works looks finished long before it is safe. Here is how to get it right, starting with the decision that saves you the most trouble.
First decision: use a provider
Unless you have a specific reason not to, do not build auth from scratch. Secure password storage, session handling, password reset, account recovery, rate limiting, these all have sharp edges, and a provider has already handled them. Your framework's auth library, or a service like Clerk, Auth0, or Supabase Auth, gives you the safe defaults for free. Rolling your own means reimplementing all of it correctly, which is exactly where AI-built auth drifts off the safe path.
Want to see exactly what Prbl flags? Watch it scan a demo app, no repo or account needed.
See a live scan →Keep the token in an httpOnly cookie
Wherever your auth comes from, the session token should live in an httpOnly cookie, not localStorage. localStorage is readable by any script on the page, so a single cross-site scripting bug steals the session. An httpOnly cookie cannot be read by script at all. This is the most common auth mistake in AI-built apps; the reasoning is in where to store a JWT, and the choice between the two approaches in session cookies vs JWTs.
Add authorization, not just login
A login answers "who are you." It does not answer "are you allowed to do this." That second question, authorization, has to be answered on every request that reads or changes data, by confirming the record belongs to the current user. AI tools build the login and skip this, which is why changing an id in a request so often reveals another user's data. The difference is explained in broken access control, and the concept in authentication vs authorization.
Rate-limit the login
Finally, put a rate limit on the login and password-reset routes so no one can try thousands of passwords a minute. A provider does this for you; if you built your own, add it explicitly. See rate limiting your login.
Frequently asked questions
Should I build my own authentication or use a provider?
Use a provider unless you have a strong reason not to. Auth has many sharp edges, secure password storage, session handling, password reset, rate limiting, account recovery, and a provider like your framework's auth library, Clerk, Auth0, or Supabase Auth has handled them. Rolling your own means reimplementing all of that correctly, which is where AI-built auth tends to go wrong. A provider gets you the safe defaults for free.
Where should the session token live?
In an httpOnly cookie, not localStorage. localStorage is readable by any script on your page, so one cross-site scripting bug hands over the session. An httpOnly cookie cannot be read by script at all, which removes that whole class of attack. This is the single most common auth mistake in AI-built apps, and it is a one-line change on the server to set the cookie correctly.
Is a login enough to protect my data?
No. A login proves who someone is; it does not decide what they are allowed to do. You also need authorization: on every request that reads or changes data, confirm the current user is allowed to touch that specific record. AI tools reliably build the login and skip this per-request check, which is why changing an id in a URL often reveals another user's data. Both steps are required.
What else does a safe login need?
Rate limiting, so attackers cannot try thousands of passwords a minute, and secure password storage with a slow hash like bcrypt if you store passwords at all. A provider handles both. If you build your own, add them explicitly, because the login will work fine without them and only fail when someone attacks it, which is exactly when you do not want to discover the gap.
Check your auth setup
A scan flags the parts of auth that go wrong most: a token exposed to the browser, a session cookie missing its flags, and an endpoint that returns data without checking who is asking. Run a free scan and see how your login holds up.