AI built your login. You sign in, it works, you shipped. What you actually shipped lets anyone submit unlimited password guesses — as fast as they can send requests.
What you shipped
The route checks the password and returns a result. There’s no limit on how many times the same IP or account can try.

How anyone exploits it
An attacker points a script at your login with a wordlist of common passwords (or leaked credentials from another breach):
for pw in wordlist: POST /login { email, pw }
With no limit, they keep going until one works. Credential-stuffing breaks weak and reused passwords in minutes.
Why you won’t catch it
You log in a few times with the right password and it works. Nobody tests by sending ten thousand wrong passwords, so the missing limit never shows up.
Why AI does it
The shortest login that “works” just checks the password. Rate limiting is infrastructure the happy path doesn’t need — one honest login never hits a limit.
The fix
Rate-limit attempts per IP and per account, then back off or lock:
rateLimit(ip, { max: 5, window: '15m' })
Add a captcha or temporary lock after repeated failures.

Check your app
- Login, password reset, and OTP endpoints are rate-limited per IP and per account.
- Repeated failures trigger a slowdown, lock, or captcha.
- You’re not leaking whether the email exists (same response either way).
The bigger problem
A senior dev catches this by reflex. But if nobody senior reads the code, the broken version ships — it works in every test, because every test takes the happy path. The author and the reviewer are the same model with the same blind spot.
That’s the gap Velify is built to close: it reads your project and flags exactly this, in plain language, no terminal.
