Skip to content

How Do I Stop People From Guessing Passwords on My Login Page?

6 min read

If your login form has no protection, nothing stops a bot from trying thousands of passwords against it. The fix is three layers you add to the login endpoint: rate limiting (cap attempts per IP and per account), lockout (freeze an account after repeated failures), and a CAPTCHA that switches on when attempts get suspicious. You need at least the first two before real users arrive.

Why this happens

When you asked your AI agent to "add login," it built the happy path: take an email and password, check them, let the user in. That works perfectly in your demo, because you type the right password once. What the agent did not add, because you did not ask, is any limit on how many times someone can be wrong.

Attackers do not sit at your login screen typing. They script it. Two attacks matter here. Brute force points a tool at one account and tries password after password until one works. Credential stuffing takes millions of email-and-password pairs leaked from other breaches and replays them against your login, betting that some of your users reused a password. Both are fully automated, cheap, and constant. An unprotected login is a door with no lock, and bots knock on every door on the internet.

How to check

You do not need a security tool. You need to see what your own login does when it is wrong many times fast.

  1. Open your login page and deliberately enter a wrong password for a real test account. Do it ten times in a row, quickly.
  2. Watch what happens. If the eleventh attempt behaves exactly like the first, with no delay, no lock, and no challenge, you have no protection.
  3. Check the network tab (right-click, Inspect, Network). If each attempt is a plain request that always returns the same "wrong password" response, a script can send that request thousands of times a minute.

If nothing slowed you down, a bot would not be slowed down either.

The fix

  1. Turn on your auth provider's built-in protection first. If you use Supabase Auth, Firebase Authentication, Clerk, or Auth0, rate limiting on sign-in exists in the dashboard settings. Enable it and set sensible limits. This is the fastest win and covers most vibe-coded apps.
  2. Rate limit the login endpoint if you rolled your own auth. Cap attempts both per IP address and per account, for example five failed attempts, then a short cool-off that grows with each further failure. Libraries like express-rate-limit (Node) or Vercel's rate limiting do this in a few lines.
  3. Add account lockout. After, say, ten failed attempts on one account, freeze it for a period and email the account owner. This stops a slow attacker who spreads attempts across many IPs to dodge the per-IP limit.
  4. Add a CAPTCHA that triggers on suspicion, not on everyone. Cloudflare Turnstile or hCaptcha can appear only after a couple of failures, so normal users never see it and bots hit a wall.
  5. Return the same generic message for "wrong password" and "no such account." Different messages tell an attacker which emails are real.
  6. Re-run the check. Repeat the ten-wrong-passwords test. You should now be slowed, locked, or challenged. If you are not, the setting did not take.

The trap to avoid

Do not rely on your front-end to enforce this. A disabled button or a "please wait" message in JavaScript stops nobody, because the attacker never loads your page. They call the login request directly, exactly the one you saw in the network tab. Rate limiting and lockout must live on the server or in your auth provider, where the request is actually handled. Client-side limits are theatre.

Where this fits

An open login is one of the first things automated traffic finds, often before you have told a single person your app exists. It is invisible in every demo and obvious to every bot. The free Readiness Report checks whether your login has real limits behind it, using your own agent against your real project, so you find out before the bots do. If you would rather have the fixes handed to you in order, that is what the Finishing Pass is for. While you are hardening auth, it is worth also sorting out password reset and deciding whether you need two-factor authentication for beta.