A password-reset endpoint answers with different wording and latency for known versus unknown addresses — what is the threat?
answer
- The response is the channel
- A yes-or-no answering component
- Identical wording is only half
- Equal work, not random jitter
- Some of it stays as residual risk
basics
~20 sThe endpoint is an information-disclosure oracle: it reveals whether an address has an account while returning no account data. Make the wording identical and the work equivalent, since timing alone still answers the question, then rate-limit and monitor bulk probing.
solid answer
~50 sThe threat is Information Disclosure on a process: the response *itself* is the channel. An anonymous caller submits an address and learns whether that person has an account here, which is a fact about a person: for a sensitive service that fact is itself the harm, and anywhere it yields a validated target list for credential attacks. Two fixes, in order. Make the response identical for both paths: same message, same status code, same body length. Then make the *work* identical, because the known path hashes a token, writes a row and queues an email, and the resulting latency difference is a second oracle that survives the first fix — hand both paths to an asynchronous job and return immediately. Add per-address and per-source rate limiting plus alerting on bulk probing. Registration and login may still leak existence, so residual risk stays on the model.
go deeper
Be ready to explain why a reset endpoint should give the same answer whether or not the address is registered, and what an attacker does with a confirmed list of real accounts.
Explain the mechanics of the second channel: which work the known-address path performs that the unknown path does not, and why that produces a stable, measurable latency difference.
Show you fix the timing as well as the copy, reject random jitter with the averaging argument, and add volume controls and detection. Interviewers expect you to separate this leak from the credential attack it enables.
Own the tradeoff: how much usability you spend hiding membership depends on what membership in this particular service reveals. Record the residual risk, its compensating controls and the trigger that would reopen the decision.
## The shape of the threat Most Information Disclosure findings are about data escaping. This one is about a *fact* escaping. The endpoint never returns a name, an address or a password — it returns a difference, and the difference answers a question the attacker asked. That pattern is an **oracle**: a system component that reliably answers yes-or-no about something you did not intend to expose, one query at a time. Record it under Information Disclosure, because the property lost is confidentiality: the membership fact reaches someone not entitled to it. Do not record it as Spoofing. No identity is being faked here. The reason candidates reach for Spoofing is that they are thinking one step ahead — a validated list of registered addresses is exactly what a later credential-guessing campaign needs — but the threat in front of you is the leak, and the downstream attack is a separate entry. ## Why the fact matters Two different harms, and a good answer names both: 1. **Target-list building.** "This address has an account" turns broad guessing into focused work, and it makes leaked-password reuse worth attempting. Volume matters: an attacker with a list of a million addresses can reduce it to the few thousand that are real. 2. **The fact is the harm.** For some services, membership is itself sensitive personal information — a health service, a support service, a service tied to a life circumstance someone has not disclosed. There, the confidentiality loss is complete at the moment of the answer, regardless of whether an account is ever attacked. Which harm dominates changes the rating, and therefore the amount of engineering the fix deserves. This is the judgment an interviewer is probing. ## The three channels, and fixing them in the right order **Wording and status.** The visible symptom: "we've sent you a reset link" versus "no account found". Collapse them into one message — a neutral "if that address has an account, we've sent a link" — with the same status code and the same body length. Watch for the near-misses: a differing redirect target, a differing `Location` header, a different validation error for an address that is well-formed but unknown, and a client that renders a different screen based on a field you thought was internal. **Timing.** This is the part that separates candidates. Even with identical bodies, the known path does real work — look up the account, generate and hash a token, write it, enqueue an email — and the unknown path does almost none. The gap is measurable and stable, so the oracle survives the copy fix intact. Two workable answers: - **Return before doing the work.** Accept the request, enqueue a job regardless of whether the address is known, and respond immediately. Response time then reflects the enqueue, not the lookup. - **Equalise the work.** Perform comparable work on the miss path — a dummy hash of the same cost — so both paths cost the same. The answer interviewers reject is **adding a random delay**. Randomness adds variance, not secrecy: an attacker who repeats the request averages it away and recovers the underlying difference. If you must use a delay, it has to be a *fixed floor* well above the real distribution, applied to both paths, and even then you are hiding rather than removing the difference. **Volume.** Oracles are only useful in bulk, so the third control targets the campaign rather than the single query: rate limit per source and per submitted address, add proof-of-work or a challenge above a threshold, and alert on a source submitting many distinct addresses with a high miss rate. This turns an invisible harvest into a detectable event. ## The part you cannot fully fix Registration usually has to tell someone their address is already taken, and account recovery has to be usable by people who mistype. Some flows therefore keep leaking membership no matter how careful the reset endpoint is, and pretending otherwise on a threat model is worse than admitting it. The mature outcome is: - Fix the reset endpoint's wording and timing, because it is cheap. - Keep the enumeration risk on the model as **residual**, with the compensating controls named (rate limit, detection) and an owner. - State the assumption that made you accept it — that membership here is not sensitive on its own — because that assumption is exactly what changes if the product moves into a sensitive category, and the model should say what triggers a revisit. ## What good looks like in the room A strong answer names the category and the property, identifies both the message and the timing channel unprompted, refuses the random-delay fix and explains why, separates this leak from the credential attack it enables, and ends on the tradeoff: how much usability you are willing to spend on hiding membership, judged by what membership in *this* service reveals about a person.
- The team makes both responses byte-identical but the leak persists. What did they miss?Latency. The known-address path looks up the account, generates and hashes a token, writes it and queues an email; the unknown path returns almost immediately. That gap is stable enough to read off with a handful of requests. Fix it by making the work equivalent — enqueue the whole operation and respond before doing it, or do comparable dummy work on the miss path — rather than by adding jitter.
- Is a random delay an acceptable defence against a timing oracle?No. Random delay adds noise around the same two means, and an attacker who repeats the measurement averages the noise away and recovers the difference. It also costs every legitimate user latency for nothing. A fixed floor above the slowest real path, applied to both branches, is defensible; true equalisation of the work is better.
- The product refuses to change the signup flow, which still reveals existing addresses. How do you record that?As accepted residual risk, written down rather than argued about. Name the threat, the reason it is accepted (usability of registration), the compensating controls — per-source and per-address rate limits, a challenge above a threshold, alerting on high-miss-rate probing — the owner, and the trigger for revisiting it, such as the service handling data where membership itself is sensitive.
- Should this be recorded as Spoofing rather than Information Disclosure?No. The property lost is confidentiality of a membership fact, so it is Information Disclosure. It commonly enables a later authentication attack, and that attack is worth its own entry, but merging the two hides which control fixes which. Keep the leak and the attack it feeds as separate rows so the mitigation for each is visible.
It is like a doorman who says "they're not in" for residents and "nobody by that name" for strangers. Even after you make him say one sentence to everyone, he still takes longer to check the resident list.
saying these in an interview costs you the question
- Fixes the message and declares the leak closed
- Proposes a random delay to hide timing
- Calls it harmless because no data is returned
- Files it as Spoofing because it precedes credential attacks
- Claims enumeration can be eliminated everywhere