Credential stuffing
The most common route by far. Attackers take username and password pairs from other services' breaches and try them against yours. No cleverness required, and it works because people reuse passwords.
What stops it:
Rate limiting on login. Per account and per IP, with escalating delays. Unthrottled auth endpoints turned up repeatedly across the 24 builds, and it's the cheapest thing on this page to get wrong.
Breach checking at registration and password change. Have I Been Pwned's range API lets you check a candidate password against known breached sets without transmitting it, you send five characters of the hash and compare locally.
Second factor. TOTP or passkeys. Even optional MFA that a minority enable meaningfully reduces the blast radius.
Watch the pattern. Credential stuffing looks distinctive in logs: many accounts, few attempts each, from rotating addresses. Per-account limits alone won't catch it.
Password reset
The second most common route, and the one most often built quickly.
Tokens must be random and long. Generated with a cryptographic random source, not a timestamp, a sequential ID or a hash of the email.
Short expiry. Fifteen minutes to an hour.
Single use. Invalidate on use, and invalidate outstanding tokens when the password changes.
Rate limit the request endpoint too. Otherwise it's a way to spam someone's inbox and to enumerate accounts.
Same response whether the account exists or not. "If an account exists, we've sent an email". Different responses tell an attacker which addresses are registered.
Invalidate sessions after reset. A user resetting their password because they suspect compromise expects the attacker to be logged out. If existing sessions survive, they aren't.
Email change
Overlooked, and it's a complete takeover on its own, change the email, then reset the password to it.
Require the current password. Send a confirmation link to the new address before it takes effect, and a notification to the old one with a way to reverse it. That notification is what turns a silent takeover into something the user can stop.
Sessions
Issue a new session identifier on login rather than reusing whatever existed, or session fixation becomes possible.
Bind sessions loosely to context. A session that suddenly appears from a different country is worth a re-authentication prompt, though be careful. Mobile users change addresses constantly and heavy-handed checks generate support tickets.
Give users a way to see and revoke active sessions.
OAuth and social login
Two specific mistakes. Trusting an unverified email claim from a provider lets someone register an unverified address with a provider and inherit an existing account. And linking accounts by email address alone means whoever controls the address controls the account.
The order
Rate limit login. Fix the reset flow. Verify email changes. Then MFA, then session management.
That order is deliberate, it follows how takeovers actually happen rather than how thorough the control sounds.