The Art of Account Lockouts The Art of Account Lockouts

The Art of Account Lockouts

Introduction: “What Is a Lockout Attack?”

Account lockout vulnerabilities let attackers intentionally trigger lockouts on a victim’s accounts, effectively locking them out. Depending on how login failures or resets are handled, this can cause real damage, especially in sensitive systems like banking or admin panels.

In this post, I’ll cover common and underrated techniques to exploit these bugs. They’re often missed in security reviews but show up in the wild more than you’d expect.

If you’re into bug hunting, grab a snack, this post will walk you through some sneaky, high-impact tricks that can lock users out without even touching their passwords.

Attack Categories

Lockout via Repeated Login Attempts

Some apps implement rate limiting to stop brute-force attacks, great in theory. But when it’s poorly done, it opens up a client-side DoA (Denial of Access (just made it up.)) where an attacker can lock out users without touching their credentials.

The most common issue? Lockouts based only on the email address, ignoring IP, user-agent, etc. That means anyone can:

  • Use a victim’s email
  • Send a few bad login attempts
  • Lock them out of their account

If the unlock process is broken or hard to reach, or not present in the first place, it’s game over.


Lockout Escalation via Brute Force

While brute-forcing a login, I noticed a rate limit. Most would stop,but I didn’t.

What I Found:

  • Delay kept increasing: 10s → 1m → 30m
  • Eventually: Account locked. Email sent to unlock.
  • But… the unlock didn’t work. It wasn’t tied to any account.

Severity: Medium
Why: Support could unlock it when requested.


Weak Fingerprinting = Permanent Lockout

This login endpoint had a 3s delay per attempt. I dug in.

What I Found:

  • Lockout was tied only to email.
  • Ignored IP, user-agent, etc.
  • I could brute-force endlessly.
  • Victim was permanently locked out with no way to recover.

Severity: High
Why: No recovery path. A true denial-of-access.


Key Notes

  • Rate limiting should use multiple fingerprints:

    • IP, User-Agent, Email, Geo (optional)
  • Don’t stop at the first rate limit, push further.

  • Always test if recovery flows actually work.


Onto the next one : )

Premature Email Sign-Up

Some platforms enforce email verification, but still register an email address before it’s verified. This can lead to premature account lockouts.

An attacker can abuse this by pre-registering someone else’s email, especially company emails effectively blocking them from signing up later.


Scenario

You see a LinkedIn post: a company announces they’ll start using platform XYZ (which is vulnerable to this issue).

You act fast and pre-register common emails like:

  • admin@company.com
  • dev@company.com
  • info@company.com

Now, those addresses are either locked in a pending state or blocked due to failed verifications.

If the platform has no solid support flow or cleanup logic, this leads to:

  • Frustration for real users
  • Failed onboarding for the company
  • Client trust loss for the platform

Surprisingly, this is still common in production apps.

Lockout via Injected Logout Request (<img src="/logout">)

Some apps let users insert links or images in their profile, chat, or shared workspace. In dev-focused apps (like code playgrounds, preview tools, or collaboration platforms), you can often link to a user profile or embed assets like images via URL. If the app has a logout endpoint that accepts GET requests (i.e., vulnerable to logout CSRF), you can abuse this by injecting something like <img src="/logout"> into any field that renders HTML, bios, team pages, shared projects, etc.

Now if a victim loads that page, the browser will auto-trigger the logout. Bonus: if the app allows profile linking, team pages, or has self-XSS, you can escalate this by injecting the logout call into your own profile and trick the victim into viewing it (e.g., by linking their account to yours). Every time their dashboard loads your profile, boom, auto logout.

💡 If you ever spot a logout CSRF, immediately look for user-controlled link points. That’s where the fun begins.


Lockout via Client-Side Redirect from Broken Pages

Some apps automatically redirect users from broken or missing pages to a fallback like /, /dashboard, or /home. These redirects are often handled client-side using JavaScript, triggered when a user visits a non-existent route like:

https://example.com/user/attacker-profile

Now let’s say the app doesn’t has a logout CSRF — good on them. But if a broken link redirects to /, and you find an injection point (like a profile bio, team page, or image src), you can trap users into an in-app redirect chain.

Any time the victim loads your crafted content, they hit the redirect → get kicked back to home → and the process can repeat if the redirect chain is re-triggered via stored state, like:

  • links stored in memory or session
  • profile preview components
  • auto-triggered image src=/ or script paths

Even if they log in again or clear cookies, the redirect re-triggers — effectively locking them out until the malicious content is removed.

This works great in collaboration tools, shared dashboards, or apps that render user-controlled paths


Lockout via Oversized Payloads (The Infamous AAAA... Attack)

This one’s a hybrid, part client-side, part server-triggered DoA.

Some web apps don’t properly handle overly long inputs like giant query params, huge route names, or absurd form values (e.g., /profile/AAAAAAAAA...). When these values are reflected back into the page ,in the DOM, in script tags, or in input fields — the browser starts to choke.

You get:

  • Page freezes
  • Memory spikes
  • Infinite rendering attempts
  • Total browser crash

Even worse: if you can store these payloads somewhere like a profile name, chat message, or shared project route, then any user who opens that page bricks their own browser.

Common abuse vectors:

  • Injected script route: /user/<huge_string>
  • Input fields pre-filled with massive values
  • <title> or <script> injections that endlessly expand

This is especially effective in:

  • Single Page Apps (SPA) where routes are client-controlled.
  • Apps with SSR (Server-Side Rendering) that reflect user input.
  • Places where user-generated content is previewed on page load.

Used in forum nukes, Discord crash videos, and even API DoS payloads. Surprisingly still alive in modern apps.

Extension — After More Research / Fiddling with These Systems

Subnet blocking.

I was testing a login system and had two Wi-Fi connections from the same ISP (PTCL). When I got locked out on one router, the other router was blocked too. After a long chat with Perplexity and a few AIs, I realized the system was banning entire subnets — not single IPs.

Some rate-limit/security systems block a whole subnet (e.g., a /16 like 123.123.x.x). That’s a range of 65,536 IPs. If both routers get IPs from that same /16, reconnecting won’t help — you’re still banned. Testing note: If you see an IP-based ban that persists across connections, check whether your addresses share the same prefix (first two octets for /16). Use ifconfig.me or ipinfo.io/ip and compare.

There are a few hurdles in testing this behaviour… like having 2 same public ips from same routers… matching in the /16 block… its impact is definitly restrained and its also hard to produce and confirm nevertheless.. its a good trick to know when testing these scenarios.

Conclusion: Lockout Isn’t Always About Rate Limits

Client-side lockouts are underrated and underexplored. While login attempt limits and rate limiting are the obvious ones, real damage often comes from creative abuse of features:

  • Cookie bombing: Reflecting Set-Cookie headers to fill up browser storage and break sessions.

  • Self-XSS: Getting a victim to execute your payload that logs them into your account, stores broken session data, and bricks their access.

  • Persistent state DoA: Using stored routes, profiles, or previews to keep triggering logouts, redirects, or crashes every time the app loads.

These are just a few of the tricks I’ve used or seen in the wild. The real fun begins when you start thinking in weird, user-specific edge cases.


Got your own twist on client-side lockouts? Hit me up on Discord. I’d love to expand this list or collab on weird bugs.

Stay sharp. Stay annoying. Happy Hacking


← Back to blog