If you build or maintain ecommerce platforms, there's a specific threat model you should be thinking about more than you probably are: account takeover (ATO) — not as a theoretical risk, but as a high-volume, automated attack class that's hitting stores right now.
The core insight is deceptively simple:
The attacker does not break in. They log in.
No code exploits. No zero-days. Just real credentials, real sessions, and stores that aren't configured to notice.
TL;DR — five checks, under an hour, no security budget required:
- [ ] Rate limit (or CAPTCHA) the
/loginendpoint after 3–5 failed attempts - [ ] Offer MFA, and push toward passkeys (FIDO2/WebAuthn) as the default
- [ ] Invalidate sessions server-side on logout — test with the browser Back button
- [ ] Log new-device / new-geo logins and notify the user
- [ ] Turn on whatever login-security features your platform (Shopify/WooCommerce/Magento) already ships with but doesn't enable by default
Scale
| Metric | Figure | Source |
|---|---|---|
| Consumers who experienced ATO in 2025 | 21% | Sift Q1 2026 Digital Trust Index |
| UK ATO fraud cases (2025) | 78,000+ (18% of all fraud, up 6% YoY) | Cifas Fraudscape 2026 |
| FBI ATO complaints (2025) | ~4,700 — first time listed as its own category | FBI 2025 IC3 Report |
| Reported losses from those complaints | $359.7M | FBI 2025 IC3 Report |
For context: ~26 billion credential-stuffing attempts per month (Akamai). Compromised credential volumes are up >150% year-over-year. This isn't a niche problem — it's the default attack surface for any store with user accounts.
The Three Vectors You Should Be Architecting Against
1. Credential stuffing
Automated login attempts using leaked username/password pairs from unrelated breaches. Because password reuse is endemic, a breach at a forum becomes a key to your checkout.
What makes this dangerous at scale: attackers are replaying real, previously-valid credentials. No brute force, no pattern — just bulk credential replay with high success rates against any login endpoint without rate limiting.
2. Session hijacking
If your session tokens lack Secure, HttpOnly, and SameSite attributes — or if you're not enforcing HTTPS at every layer — session cookies are extractable on shared networks. A café attacker with mitmproxy or a rogue AP can capture sessions without knowing the password.
A correctly-flagged session cookie looks like this:
Set-Cookie: session=abc123; Secure; HttpOnly; SameSite=Strict; Path=/
Even with HTTPS, SameSite=None on session cookies is still common in cross-origin setups (e.g. embedded checkout widgets, third-party payment iframes). Worth auditing — SameSite=None requires Secure and reopens some of the cross-site exposure the other flags are meant to close.
3. AI-assisted phishing
The phishing bar just got much lower. LLMs generate convincing, brand-accurate login page clones at scale. The old advice — "look for typos" — doesn't apply when the attacker can clone your exact HTML, match your brand voice in emails, and serve a pixel-perfect fake checkout from a lookalike domain.
Five Things to Check (Or Tell Your Team to Check)
These aren't aspirational — they're configuration-level fixes that should take under an hour.
1. Rate limiting on login
Quick test: enter a wrong password 10 times. If nothing happens — no CAPTCHA, no progressive delay, no lockout — you have no rate limiting.
What to implement: progressive throttling or CAPTCHA after 3–5 failed attempts per account or per IP. Most platforms have plugins or middleware for this. If you're building custom, a token bucket or sliding window limiter on the /login endpoint is non-negotiable:
# Minimal sketch — swap in Redis for real deployments
from time import time
attempts = {} # key -> [timestamps]
WINDOW = 300 # 5 minutes
LIMIT = 5
def is_rate_limited(key):
now = time()
attempts[key] = [t for t in attempts.get(key, []) if now - t < WINDOW]
if len(attempts[key]) >= LIMIT:
return True
attempts[key].append(now)
return False
Key on account and IP separately — attackers rotate IPs (residential proxies), and legitimate users share IPs (offices, NAT).
2. MFA — ideally passkeys
If your platform supports customer-facing MFA, enable it. Even opt-in gives security-conscious users a way to protect themselves.
But the real win is passkeys (FIDO2/WebAuthn). Passwords are the root cause of credential stuffing — remove the password and the attack vector collapses, since there's no shared secret left to steal, leak, or replay.
Separately, passkeys also outperform passwords on plain usability — the FIDO Alliance's 2025 Passkey Index found a 93% login completion rate for passkeys vs. ~63% for password-based methods. That's a UX/conversion number (how often a real user finishes logging in), not a measure of attack resistance — but it means the security upgrade doesn't come at the cost of friction, which is usually the objection that kills MFA rollouts.
Major platforms (Amazon, Google, PayPal, TikTok) are already rolling out passkey support. If you're building auth for a new platform, FIDO2 should be the default, not the upgrade.
3. Server-side session invalidation
Quick test: log in → click logout → press browser Back. If the dashboard renders, your session tokens aren't being invalidated server-side on logout.
This is a common misconfiguration in stateless token setups where the server trusts the client to "forget" the token. Server must explicitly invalidate or blacklist the session on logout. For JWT-based sessions, a short TTL + token blacklist or rotation is the fix.
4. Suspicious login detection
At minimum: flag logins from new devices or unusual geolocations and notify the user. If you're not building this, most platforms (Shopify, WooCommerce, Magento) have plugins for basic login activity logging.
For custom builds: a simple user_sessions table tracking ip, user_agent, geoip, and last_seen lets you flag anomalies without a full SIEM.
5. Audit your platform's security features
If you're on Shopify, WooCommerce, or Magento — review the built-in security settings. These aren't glamorous, but they matter:
- Login attempt monitoring
- IP-based throttling
- Suspicious activity flags
- Session timeout configuration
Make sure they're turned on and configured, not just "available."
The Architectural Takeaway
ATO isn't a vulnerability you patch — it's a configuration and design surface. The most effective mitigation is layered: rate limiting at the edge, MFA/passkeys at auth, proper session lifecycle management, activity logging, and sensible platform defaults.
None of this requires a security budget. Most of it requires someone to actually check whether these features are enabled.
The question isn't whether someone is trying to log in as your customers. It's whether your store is configured to notice — and whether it's harder to attack than the one next door.
Originally published on the WardenBit Blog, covering practical ecommerce security for developers and shop owners.
Top comments (1)
Solid list, and the "they log in, they don't break in" framing is exactly right. The one I'd push on is #4 — new-device/new-geo detection looks like it catches ATO but quietly fails worst, because geolocation is a property the attacker can just rent. Residential proxy networks sell geo-targeted exits, so someone running stolen creds buys an exit in the victim's own city and the "new location" check sees nothing unusual, while your real customer traveling abroad on hotel WiFi is the one who trips the alarm. The signal that doesn't invert like that is the network the login actually comes from — a consumer ISP versus a hosting range or a known proxy pool — because that's the part they can't easily launder even when the city lines up. Cheap to eyeball with something like ipasis.com/scan if you want to see how a given IP classifies before you let "same city" buy any trust.