Account Takeover (ATO)
Also Known As
ATO
account compromise
TL;DR
An attacker gains full control of a user account through credential stuffing, phishing, session hijacking, or abusing password-reset flows.
Explanation
Account takeover aggregates multiple attack vectors: credential stuffing (testing breached username/password pairs at scale), password spraying (common passwords against many accounts), phishing (fake login pages), session hijacking (stolen cookies), and broken password-reset flows (predictable tokens, user-enumeration, host-header injection in reset emails). Defences form layers: bcrypt/argon2 password hashing, rate limiting login and reset endpoints, multi-factor authentication, breach-password detection (HaveIBeenPwned API), login anomaly detection (new device/IP), secure HttpOnly+SameSite session cookies, and short-lived password-reset tokens bound to the requesting IP stored as a hash.
Diagram
flowchart TD
subgraph Attack Vectors
CRED[Credential Stuffing<br/>leaked passwords]
PHISH[Phishing<br/>fake login page]
SIM[SIM Swap<br/>bypass SMS 2FA]
SESS[Session Hijack<br/>steal cookie]
RESET[Password Reset<br/>weak flow]
end
subgraph Defences
MFA[Strong 2FA<br/>TOTP not SMS]
RATE[Velocity checks<br/>per account]
NOTIF[Login notification<br/>email on new device]
CSESS[Concurrent session<br/>detection]
RECOV[Secure recovery flow<br/>identity verification]
end
CRED --> MFA
SIM --> MFA
PHISH --> NOTIF
SESS --> CSESS
RESET --> RECOV
style MFA fill:#238636,color:#fff
style RATE fill:#238636,color:#fff
style NOTIF fill:#238636,color:#fff
Watch Out
⚠ Password-reset flows are the most common ATO entry point — sending a reset link to an attacker-controlled email after an unverified email-change is a critical flaw seen in many production systems.
Common Misconception
✗ Account takeover always requires stealing a password. Attackers frequently take over accounts via password reset flaws, session fixation, or OAuth misconfigurations — no password needed.
Why It Matters
A compromised account gives an attacker full control of a user's data and identity; if that account has elevated privileges, the blast radius extends to all users.
Common Mistakes
- Not invalidating all existing sessions after a password change.
- Weak or predictable password-reset tokens that expire too slowly.
- No rate-limiting on login, reset, or OTP endpoints.
- Trusting client-supplied user IDs in session data rather than reading from the server-side session.
Avoid When
- Do not implement security theatre (e.g. re-CAPTCHA only) without layered controls — bots solve CAPTCHAs routinely.
- Avoid storing session tokens in localStorage — XSS can exfiltrate them; use HttpOnly cookies instead.
When To Use
- Apply ATO defences on any account that controls money, data, or downstream user trust (admin accounts, payment accounts, OAuth providers).
- Use this threat model when reviewing login, password-reset, session management, and email-change flows.
Code Examples
💡 Note
The bad example allows an email change with only a valid session — no re-authentication — so a stolen session cookie grants permanent account control.
✗ Vulnerable
// No re-auth required — attacker with stolen session can change email
public function updateEmail(Request \$req): Response {
auth()->user()->update(['email' => \$req->email]);
return response()->json(['ok' => true]);
}
✓ Fixed
public function updateEmail(Request \$req): Response {
// Require current password for sensitive account changes
if (!password_verify(\$req->current_password, auth()->user()->password)) {
return response()->json(['error' => 'Password incorrect'], 403);
}
\$newEmail = \$req->validate(['email' => 'required|email|unique:users'])['email'];
// Send verification to NEW address before applying
\$token = bin2hex(random_bytes(32));
Cache::put('email_change:' . \$token, ['user_id' => auth()->id(), 'new_email' => \$newEmail], now()->addHour());
Mail::to(\$newEmail)->send(new VerifyEmailChange(\$token));
return response()->json(['message' => 'Check your new email to confirm the change']);
}
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
31 Mar 2026
Views
27
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Perplexity 8
Amazonbot 8
Google 2
Unknown AI 1
SEMrush 1
ChatGPT 1
Ahrefs 1
Also referenced
How they use it
crawler 21
crawler_json 1
Related categories
⚡
DEV INTEL
Tools & Severity
🔴 Critical
⚙ Fix effort: High
⚡ Quick Fix
Audit the full authentication flow: password reset tokens (random_bytes), session regeneration on login, rate limiting on all auth endpoints
📦 Applies To
PHP 5.0+
web
🔗 Prerequisites
🔍 Detection Hints
Password reset using md5/time/mt_rand token or missing session_regenerate_id after login
Auto-detectable:
✗ No
semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium
False Positives: Medium
✗ Manual fix
Fix: High
Context: File
Tests: Update
CWE-287
CWE-620