Authentication failures come in many shapes. The verifier doesn't rate-limit; registration accepts any password; error messages reveal who exists.
No lockout means the verifier's rate matches the attacker's HTTP throughput. Common-password lists land in seconds.
if USERS.get(u) == md5(p):
return 'ok'
ATTEMPTS[u] += 1 # counted but never enforced
Try password, 123456, admin — nothing stops you.
Attempt counts climb forever. Real apps lock after 5 failures.
Failed attempts on admin: 1