Somebody mentions that a password you have been using for years turned up in a data breach. The obvious way to settle it is to type that password into a website and see what comes back, which is also why most people never settle it. Typing a live password into a stranger's form is the exact behaviour every security guide warns about in its first paragraph.

The check does not have to work that way. A properly built breach lookup never receives your password, never receives its full hash, and could not tell which password you asked about even if it wanted to. It sends five characters. What follows is what they do, and what the answer is worth.

The question, and why it sounds dangerous#

The threat that makes this worth checking is credential stuffing, which OWASP describes as the automated injection of stolen username and password pairs into login forms to fraudulently gain access to accounts. No cleverness is involved. An attacker takes credentials that leaked from one site and replays them against a hundred others, and it works because people reuse passwords.

How often? OWASP cites an analysis of the 2011 Sony breach finding that two-thirds of the users who appeared in both that data set and the earlier Gawker breach had used the same password on both. Reuse is the default human behaviour, not an edge case.

So the useful question is not "is my password strong". It is narrower and much more answerable: is this specific string already sitting in a list that attackers can download? If it is, no amount of length or symbol variety helps. The guessing step has already been skipped.

What a breach corpus actually holds#

The corpus behind these checks is not a table of accounts. Have I Been Pwned's Pwned Passwords data is a list of password hashes with a prevalence count next to each one, stripped of any connection to the email address or the site it came from. It says only that this string has appeared in breach data, and roughly how often.

That is why the question can be answered safely at all. You are not asking a service to look you up, only whether a string appears in a published list.

The list keeps growing, increasingly from a source unrelated to any one company being hacked. In June 2026, Have I Been Pwned absorbed accumulated infostealer logs covering 56.3 million unique email addresses and 124 million unique passwords, harvested from malware sitting on individual machines rather than lifted from a breached database. A password can land in the corpus because some computer was infected, not because a site you use was compromised.

Five characters, and a bucket of a million#

The mechanism has a name: k-anonymity.

Your browser hashes the password locally with SHA-1, producing 40 hexadecimal characters. It then sends the first five of those characters, and nothing else, to https://api.pwnedpasswords.com/range/. Five hex characters have 165 possible values, which is 1,048,576 distinct buckets. Your hash falls in one of them, alongside every other hash on earth that happens to begin with the same five characters.

The service replies with every breached hash in that bucket, listed as the remaining 35 characters, a colon, and a prevalence count:

0018A45C4D1DEF81644B54AB7F969B88D65:1
00D4F6E8FA6EECAD2A3AA415EEC418D38EC:2

Your browser then searches that list for its own 35-character suffix. The comparison happens on your machine, over data the server volunteered without being told what to look for. It saw five characters shared by a vast number of possible passwords, and never saw the other 35.

That asymmetry is the whole trick: enough to find the right shelf, not enough to identify the book.

SHA-1 is broken, and that is fine here#

Anyone who has read about hashing will flinch at SHA-1. In February 2017, researchers at CWI Amsterdam and Google published SHAttered: two visibly different PDF files that share one identical SHA-1 digest. The algorithm's core promise had been broken in practice rather than in theory.

That result is a collision attack: the researchers constructed two inputs with the same output. It is not a preimage attack, which would mean recovering an input from a digest. The distinction matters, because nothing in a breach check is being signed or authenticated. The hash is a lookup key into a published list, the corpus is keyed on SHA-1, so SHA-1 is what you have to compute to search it. The privacy comes from sending 5 characters out of 40, not from the strength of the algorithm.

Our explainer on hashing covers why a digest only travels in one direction, and the hash generator will compute SHA-1 or SHA-256 for any string. Do not paste a live password into it, or into any hash tool. That is the habit this whole design exists to avoid.

What the size of the reply gave away#

There is a subtle leak in the design so far. Buckets are not all the same size. If one prefix returns a few hundred records and another well over a thousand, anyone who can see the size of an encrypted response, without reading it, can start narrowing down which bucket was requested. Traffic analysis undoes some of the anonymity the five-character trick bought.

The fix is padding. A client can send the header Add-Padding: true, and the service documents that results then contain a random number of records between 800 and 1,000. The extra rows are decoys, each given a prevalence count of 0.

Zero is deliberate rather than arbitrary. A genuine entry can never have a count of zero, because a password with zero appearances would not be in a breach corpus at all, so the filter is exact instead of a guess. Getting it wrong produces the worst answer available: a decoy row matching your suffix reported as found, seen 0 times, which reads to a user as located and cleared.

Reading the number that comes back#

If your suffix is in the list, you get a count. Be precise about what that number is and is not.

  • It is the number of times this password has appeared across the breach records in the corpus.
  • It is not a count of your accounts. The corpus holds no identities at all.
  • It is not a severity score. A count of 4 and a count of 4,000,000 both mean the string sits in a file that anyone can download.

What prevalence predicts is speed. A password seen millions of times sits near the top of every cracking wordlist and gets tried in the first seconds of an attack. One seen twice gets tried later in the same run. Both get tried.

The response is the same either way. Stop using that password everywhere it is in use, starting with the accounts that matter most, and do not carry any part of it into the replacement. If it guarded an email account or a password manager, treat everything reachable from there as exposed too: a mailbox is where password resets land.

Not found is not a clean bill of health#

This is where a lot of breach checkers do their readers a disservice, usually with a green tick.

A password absent from the corpus has been shown to be absent from a collection of breaches somebody gathered and published. That is the entire finding. It can still be short, guessable, sitting in a dictionary, reused across a dozen sites, or present in a breach nobody has disclosed yet. Absence is evidence of one narrow thing, and strength is not that thing.

Our own password breach check refuses to show a positive verdict for exactly this reason. A password that is not in the list gets an explicitly uncertain result and a sentence spelling out what was established, because a green tick would be a claim the data cannot support.

It helps to know what ignoring this looks like from the defending side. When a reused password is replayed successfully, the first visible sign is often a sign-in from a place the account has never been used, the pattern behind impossible travel alerts. Those alerts are often the downstream consequence of a password that entered a list months earlier.

What the standard actually asks for#

Breach checking is not a nice-to-have in current guidance. NIST's digital identity guidelines, SP 800-63B, state in section 3.1.1.2 that when processing a request to establish or change a password, verifiers shall compare the prospective secret against a blocklist containing known commonly used, expected, or compromised passwords, and that the entire password shall be subject to comparison rather than substrings within it. Passwords obtained from previous breach corpuses are named as material for that blocklist.

The same section reverses two rules many organisations still enforce. Verifiers shall not impose composition rules, such as requiring a mixture of different character types. Verifiers shall not require users to change passwords periodically, though they shall force a change where there is evidence the credential has been compromised. Length carries the weight instead: a minimum of 15 characters for a password used as a single factor, and eight only where it forms part of multi-factor authentication.

That is a different shape of password hygiene from the one most people were taught: long, unique, not rotated on a calendar, and checked against known breach data at the moment it is chosen.

Checking one yourself#

Our password breach check implements the flow above. The hashing happens in your browser through the WebCrypto API, and the request for the bucket goes straight to Have I Been Pwned rather than through our servers, so we never see even the prefix. Padded rows are discarded before the match runs, so a decoy can never be reported as a hit.

Because a privacy claim you cannot inspect is worth very little, the result panel shows its working: the five characters that were sent, the 35 that stayed on the page, that the request named one bucket out of 1,048,576, and how many real breached hashes came back inside it. Open your browser's network panel while you run a check and every one of those claims is verifiable in seconds.

One consequence is that the tool has no fallback. If an extension, ad blocker or corporate proxy blocks the request, the check fails and says so: the only fallback available would be routing your hash prefix through our servers, giving away the one thing the design protects.

The underlying API is free, needs no key or subscription, and publishes no rate limit, which is part of why many password managers already run this check on your behalf. If yours does not, putting a password you care about through it takes about ten seconds. Finding out that a password is on the list is unpleasant. Finding out from whoever used it is worse.

Try it

Check a password against the breach corpus

Your browser hashes it locally and sends five characters straight to Have I Been Pwned, never to us. The result shows exactly what was sent and what was kept.

Check a password →