Password Exposure Checker
Built with: TypeScript · Web Crypto API · k-anonymity · Content Security Policy
The problem
"Don't reuse passwords" is advice everyone has heard and few act on, because the risk feels abstract. Showing someone that their password appears in millions of breach records changes behaviour quickly. The catch is that typing a real password into a website is precisely what security training tells people never to do.
Who it's for
Security awareness leads, IT teams, and anyone who has to explain credential risk to people who are not security engineers, and who needs a demo they can hand over without creating a new risk.
How it works
- The password is hashed with SHA-1 in the browser using the Web Crypto API.
- Only the first five characters of the hash are sent to the public Pwned Passwords range API, with response padding turned on so the reply size gives nothing away.
- The API returns every hash suffix sharing that prefix, and the match happens locally. The service never learns which suffix, if any, you were checking.
- Nothing is stored. The page's Content Security Policy allows exactly one outside host for this, so the browser itself enforces where data can go.
- The matching logic is a small pure module with no browser or network dependencies, so it can be unit tested in plain Node.
Try it
Open the Password Exposure Checker. Try password123 to see a hit, then read the panel that shows exactly what left the page.
The 30-second pitch
"This lets someone check a real password without trusting us with it. Only a five-character fragment of a hash ever leaves the device, and the browser enforces that. It turns 'stop reusing passwords' from a lecture into a two-second moment of 'oh'."
What I'd ask in a first call:
- Do you check for breached passwords at sign-up or reset today?
- Where do people store passwords now: a manager, the browser, or memory?
- Is the goal awareness, or enforcement in your identity provider?
Trade-offs and limits
- It tells you a password has been seen in a breach. It cannot tell you a password is strong or has never leaked.
- It is an awareness tool. In production, the same check belongs in the sign-up and reset flow of your identity provider, not on a separate page.
- It depends on a third-party API being available. If that API is unreachable, the page shows an error rather than a false all-clear.