← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Account Takeover (ATO)

Security CWE-287 OWASP A7:2021 CVSS 9.8 PHP 5.0+ Intermediate
debt(d7/e7/b7/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). While semgrep is listed as a tool and can catch specific patterns like md5-based tokens or missing session_regenerate_id, the detection_hints explicitly state automated detection is 'no'. ATO vulnerabilities span multiple flows (login, password reset, session management, OAuth) and most of the common_mistakes (missing session invalidation after password change, no rate limiting, trusting client-supplied user IDs) require careful manual code review or penetration testing to identify comprehensively. A single semgrep rule catches only a narrow slice.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix says 'audit the full authentication flow' covering password reset tokens, session regeneration, and rate limiting on all auth endpoints. The common_mistakes span login, password reset, session management, and OTP endpoints — these are distinct subsystems. Fixing all ATO vectors requires changes across multiple files and components (session handling, token generation, rate limiting middleware, email-change flows). This is not a single-line fix but a cross-cutting security hardening effort.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). ATO defences touch authentication, session management, password reset, OAuth, and rate limiting — these are cross-cutting concerns that shape how every auth-related feature is built. Every new feature involving user identity (email change, 2FA enrollment, API key management) must consider ATO. The tags (authentication, session, owasp-top10) confirm this is load-bearing across the system. It doesn't quite reach b9 because it's scoped to auth flows rather than defining the entire system architecture.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field is explicit: developers believe ATO 'always requires stealing a password,' when in reality attackers frequently use password reset flaws, session fixation, or OAuth misconfigurations — no password needed. This is a serious cognitive trap because a competent developer focused on password security (strong hashing, breach detection) will believe they've addressed ATO while leaving session fixation, weak reset tokens, and missing session invalidation completely unguarded. The mental model of 'protect the password = protect the account' is intuitive but dangerously incomplete.

About DEBT scoring →

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']);
}

Added 15 Mar 2026
Edited 31 Mar 2026
Views 104
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 1 ping W 3 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 3 pings T 8 pings F 4 pings S 16 pings S 9 pings M 2 pings T 0 pings W 1 ping T 0 pings F 2 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 2 pings S 0 pings S 2 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 40 Google 11 Perplexity 9 Amazonbot 9 SEMrush 4 ChatGPT 4 Ahrefs 3 Unknown AI 1 Claude 1 Bing 1 Meta AI 1 Sogou 1 PetalBot 1
crawler 83 crawler_json 3
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


✓ schema.org compliant