skip to content

A signed-in member changes their own password — why demand the current one, and where do the password rules belong?

level: middleimportance: must knowfreq 62%

answer

  1. who is at the keyboard now
  2. the credential replaced, not presence
  3. one routine behind every write path
  4. sign-up, change, officer set, import

basics

~20 s

Re-entering the current password proves knowledge of the exact credential being replaced — something an unattended signed-in browser cannot supply. The rules validating the new value belong in one shared routine behind every write path, not on the change form.

solid answer

~50 s

Being signed in proves somebody authenticated earlier; it says nothing about who is at the keyboard now. Re-entering the current password is a knowledge proof of the exact credential being replaced, which an unattended signed-in browser cannot supply and a fresh possession challenge does not give you — that shows a device is present, not that its holder knows the secret being retired. The second half of the answer is placement. List every server path that can store a password: self-registration, self-service change, an officer setting one for a member, a bulk import, an internal support endpoint. Put the rule set and the change event in one routine all of them call, and assert each path's own precondition there. A rule that lives on the registration form is a property of that screen, not of the system.

code

pseudocode · 15 lines
pseudocode
# every entry point funnels into one routine; none of them validates on its own

POST /members/signup
    -> set_password(new_member, value, {kind: "self_registration"})

POST /members/me/password
    -> set_password(me, value, {kind: "self_change",
                                current_password: submitted_current})

POST /officers/members/{id}/password
    -> set_password(id, value, {kind: "officer_set", actor: signed_in_officer})

CLI  import-legacy-members
    -> for row in file:
           set_password(row.member, row.value, {kind: "bulk_import"})

go deeper

for a junior

Remember the demand and its reason: the change screen asks for the current password because being signed in only shows somebody signed in earlier, not who is typing now.

for a middle

Be able to walk every server path that can store a password — sign-up, self-service change, an officer set, an import, a support endpoint — and say where the single validation point sits behind them.

for a senior

Show the failure you have actually seen: rules on one form, a second path writing rows that break them, nobody noticing for a year. Then name what the shared routine emits so the rest of the system hears about a change at all.

for a principal

The tradeoff is where the invariant is guaranteed. One routine is cheap to extend and awkward for teams who want their own endpoint; a rule repeated per path ships faster and drifts silently, and you pay for that drift in an audit rather than an incident.

A password change on a signed-in screen looks like a form with three boxes. The engineering sits in two questions the form does not show: what the server demands before it accepts the change, and which code the new value passes through before it is stored. ## What a session reference proves, and what it does not When a member opens the change screen on a federation's rating-submission site, the server already knows who they are: the request carries a reference to a session record issued when they signed in. That reference proves one thing — somebody signed in as this member at some earlier moment. It says nothing about who is typing now. A laptop left open at the congress hall, a shared club machine nobody signed out of, a housemate at the desk: all ordinary, boring and common. Re-entering the current password is a **knowledge proof of the exact credential being replaced**. It is narrow on purpose: | Proof offered | What it establishes | What it fails to stop | |---|---|---| | A valid session reference | Somebody signed in as this member earlier | Anyone who later reaches that signed-in browser | | A fresh challenge on the enrolled authenticator | That authenticator is present right now | Someone holding the browser and the unlocked authenticator together | | Re-entering the current password | Whoever is typing knows the secret being retired | Someone who already knows that password | The third row is the only one aimed at the credential in question. A possession challenge proves a device is present; it does not show that the person driving it knows the value they are about to replace. That is why the two controls are not substitutes. A strong answer also states the limit out loud: the re-proof does nothing against an attacker who already has the password. Stopping that is a different control's job. ## Every server path that can put a password in a member's row The second half of the subject is placement, and the argument starts by enumerating the writers rather than debating the rules: 1. **Self-registration** — a new player creates an account. 2. **Self-service change** — the member replaces their own value. 3. **An officer-initiated set** — a federation officer sets one for a player who cannot get in before a congress. 4. **A bulk import** — a club's legacy member list is loaded in one go. 5. **An internal support endpoint** — the one nobody remembers until it turns up in a review. A rule that lives only on the registration form is not a rule. It is a property of one screen. Rows arriving through the other paths will violate it, nothing will complain, and the violation stays invisible until somebody runs a query nobody has thought to write. Assume a sixth path appears next quarter, because one usually does. ## One routine behind all of them The fix is structural rather than a matter of discipline: - One routine takes the subject, the new value, and a **context** naming which path is calling. - The rule check runs there, once, for every caller. - Each path's own precondition is asserted there too: the self-service path must present a current password that verifies, while a path where no current password exists must instead prove the caller's authority to act on someone else's account. - The stored value is written and the change event emitted from the same place, so no path can write without announcing it. - Adding that sixth path becomes a call to the routine rather than a copy of its contents. Client-side checks stay, but as a convenience that saves a round trip. They enforce nothing: anything reaching the endpoint directly skips them entirely. ## The change is an event, not just a write A successful change matters to code nowhere near the form. Other parts of the system want to know that this member's credential was replaced, when, and whether the member did it themselves or somebody acted on their behalf. This routine's responsibility is that the event is emitted exactly once, from one place, for every path. What the consumers then do — what is torn down, what the member is told, what has to be re-enrolled — is decided elsewhere and is not the change endpoint's call. ## What an interviewer is listening for - That the re-proof is about the *credential*, not about the *person being present*, and that those are different claims. - That the candidate enumerates write paths unprompted instead of describing only the screen they built. - That validation and the event sit behind the paths rather than beside each one. - That the limits get said: neither control helps once the password itself is known, and client-side validation enforces nothing.

  • The change screen and the sign-up form both validate, but a club's bulk import does not. What breaks?
    Rows land that no interactive path would have accepted, and nothing reports them — the invariant is only as strong as its weakest writer. The fix is not to copy the validator into the importer; it is to make the importer call the same set-password routine the screens call, so there is one rule rather than three that drift.
  • Why is a fresh challenge on the member's enrolled authenticator not a substitute for re-entering the current password?
    They prove different claims. The challenge shows the enrolled authenticator is present; the current-password prompt shows that whoever is typing knows the secret being retired. Someone sitting at an unattended, signed-in browser with the phone beside it satisfies the first and fails the second, which is the case the prompt exists for.
  • An enterprise directory's own change operation treats the current password as an optional field. Does that let your server skip it?
    No. Your server decides its own precondition before it forwards anything downstream; optional there means the downstream will happily accept a set with nothing proved. Demand the re-proof in your shared routine, then call the directory. What a protocol permits is a statement about the protocol, not about your policy.

Bolting the front door while the side door stays on the latch. The rule is not a property of the house until every door has it — and the door you forgot is the one that never had a form on it.

saying these in an interview costs you the question

  • The session cookie already proves it is them, so the old password is redundant.
  • A fresh second-factor prompt is the same proof as re-entering the current password.
  • Validation lives on the sign-up form; the change screen inherits those rules.
  • Imports and internal support tools are ours, so they can skip the rule set.
  • The change is finished once the row is written; nothing else needs to hear about it.