All posts

May 5, 2026 · 4 min read

Does Your Login Form Respond Faster for Accounts That Don't Exist?

I've written before about making sure a login or password-reset form gives an identical response whether an account exists or not, so someone can't build a list of real email addresses by watching how the message differs. There's a subtler version of this same leak worth its own post: even when the message looks identical, how long the app takes to respond can still give the answer away.

Why timing can leak the same information a message would

A common way login logic gets built: look up the account by email, and if it exists, compare the submitted password against the stored one. If it doesn't exist, skip the comparison step entirely and return the same generic error message. The message is identical either way, which looks correct. The problem is that the password comparison step takes a small amount of real time to run, and skipping it for a nonexistent account means that response comes back measurably faster than one where the comparison actually happened.

Why this is worth caring about even though it sounds minor

A single request's timing difference is genuinely tiny, often milliseconds, and not something a person would notice by hand. It's also exactly the kind of pattern an automated script can detect reliably by sending many requests and measuring the average response time for different email addresses, effectively rebuilding the same "does this account exist" information the identical error message was specifically designed to hide.

How to actually think about whether this applies to you

This is a more advanced, lower-priority item than most of what's on this blog, and I want to be honest about that. For a small app without a specifically high-value or high-risk user base, this is a real but lower-priority gap compared to the access-control basics that cause almost every actual incident I write about. It becomes worth deliberate attention once account existence itself is sensitive information, an app where being a user at all reveals something someone might not want known, or once you're specifically hardening an app against a more sophisticated, motivated attacker.

What the fix actually looks like

The standard approach is to make both paths take a comparable amount of time regardless of whether the account exists, either by always running a password comparison against some placeholder value when no real account is found, or by adding a deliberate, consistent delay to both paths. Most well-established authentication libraries already handle this correctly by default, which is one more reason to lean on a mature, dedicated auth solution rather than a custom-built login flow, a point I've made before for different reasons.

I'm including this one specifically to be honest about where the checklist gets genuinely advanced, rather than implying every post on this blog carries equal urgency. Fix your access rules and your exposed keys first. This is a real, legitimate concern, and it's further down the list for most small apps than nearly everything else I've written about this year.

Related reading

Harbova is a security service for apps built with AI tools. Start with a free scan, and if it finds something serious, we can fix it and prove it is closed.