What a local leaked-password list can prove, and why it is not a full-web lookup

“Check whether this password has been leaked” is often treated as one job. It is at least three: hand the plaintext to a website, send a hash prefix to Have I Been Pwned, or match a public high-frequency list in this tab. The check is not the word “local” on the page. It is which of those three the request actually did—and which sentence a hit or a miss can support in a ticket.

Start with the conclusion: a local weak-password list can support only one narrow claim—“does this string look like a password that is already widely abused.” A miss does not prove it never appeared in a breach dump. A hit only means it is too common and should be replaced now. Have I Been Pwned’s password range query is a different protocol: it sends the first five characters of a SHA-1 hash. Before you paste plaintext into any “online checker,” confirm which of the three you are about to run.

Answer the search intent in one sentence

A local leaked-password list can prove only this: the string you typed can or cannot be matched against the public high-frequency list already downloaded into this tab. It cannot prove “never seen on the web,” and it cannot answer “has my email appeared in a breach.” Have I Been Pwned (HIBP) Pwned Passwords range queries are a separate path: this device computes SHA-1 and sends only the first five hex characters to https://api.pwnedpasswords.com/range/{prefix}; the remaining suffix is compared on the client.

This article is for developers and ops who want to “just check” an old password, and for support staff handed a link to an “online password checker.” It does not replace the Password Audit how-to, and it does not repeat the Network walkthrough for “did local encryption upload plaintext.” What you should take away is what each method sends off this machine, how far a local list’s variants go, and which sentence a hit or a miss can actually go into a ticket.

Three “breach checks” are not the same job

Search “check if my password was leaked” and the results mix protocols that have nothing in common. Some sites POST whatever you typed. Some call HIBP’s k-anonymity range API. Some download a short word list and look it up in the browser. All three can paint “not found” or “pwned” on the same kind of badge. The request line is different, and so is the claim you can defend.

The OWASP Authentication Cheat Sheet tells sign-up and password-change flows to block common and compromised passwords, and it names both Pwned Passwords and public lists such as SecLists. It does not treat an 800-line local list and a billion-hash corpus as the same evidence. If a ticket only says “checked, not leaked,” the next reader cannot tell which net you used.

Method What leaves this machine What a miss can support
Upload plaintext or a full hash The password itself, or a digest that is enough to compare or recover it Only that this site did not flag it this time—not that it is safe
HIBP range query The first 5 hex characters of a SHA-1 or NTLM hash This hash is not in HIBP’s current index
Local public high-frequency list The list file itself; the password you test stays in the tab This short list and its variant rules did not match

The third method still uses the network: the browser GETs the list file. That file is a public word list, not your password. Treating every request as “it went online, so the password was uploaded” misreads the boundary. Treating the word “local” on the page as proof misses the first kind of site.

Do not test with a production vault password, an unrotated API token, or an online-banking PIN. Invent a canary that exists only for this check—for example CanaryPwd-20260902-xK9. You are checking whether this request carried that string, not exposing a real secret a second time.

What the local list actually matches

On FastPwd’s Password Audit page, the list is fetched from the same-origin path data/leaked-top10k.txt, then built into a lowercase-key-to-rank table in this tab. The filename says top10k because that is how public high-frequency lists are often named. Open the response and you can count just over 800 non-empty lines; they start with 123456, password, qwerty—strings that show up in dump after dump. Product copy never calls that file “10,000 entries” or “every breach on the web.”

The lookup is not a single equality test. The implementation runs four stages. A hit at any stage marks the password red and forces the grade to Weak.

  1. Exact match: the input equals a list entry.
  2. Case fold: lowercase first, so Password and password are the same entry.
  3. Strip a trailing 0–999: qwerty123 is reduced to qwerty, then looked up.
  4. Common leet: @/4→a, 3→e, 1/!→i, 0→o, 5/$→s, 7→t. The same step can run after the trailing digits are stripped.

If the input is longer than 128 characters, the last two stages do not run—only exact and case-folded match. If the list file fails to load, the page falls back to a built-in minimum set: password, 123456, 12345678, qwerty, admin123, and the status line still says the check finished on this device. Rank is only used for the hint: Top 100, Top 500, Top 1,000, or a fallback “Public leaked list.” That is not HIBP’s “seen N times” count.

NIST SP 800-63B-4 asks verifiers, at account creation and password change, to compare the candidate as a whole string against a blocklist of common, expected, or compromised passwords—not as a substring—and it says not to stack a separate composition-rule set on top. A local high-frequency list covers the layer “block the ones attackers guess first.” The file is far smaller than the dictionaries attackers spray, and far smaller than the breach hashes HIBP keeps merging in. In June 2026, HIBP’s June 2026 Stealer Logs ingest alone added about 124 million unique passwords. Just over 800 public high-frequency words will catch 123456. They will not catch a long passphrase that appeared only in one internal dump.

What an HIBP range query sends—and what it does not

HIBP’s own passwords page says a miss “doesn’t necessarily mean it’s a good password, just that it hasn’t been found in any of the data this site holds.” The protocol is documented in API v3 · Pwned Passwords. The client hashes the password with SHA-1 (or NTLM when mode=ntlm), takes the first five hex characters, and requests GET https://api.pwnedpasswords.com/range/{prefix}. The server returns every suffix under that prefix plus a seen-count. The remaining 35 characters of the 40-character hash stay on this device for comparison.

The published scale is something you can check on the spot: a range query usually returns about 800 suffixes; the prefix space is 165 = 1,048,576 values, from 00000 to FFFFF, and every prefix should return HTTP 200—not 404. An optional Add-Padding: true header pads the response to 800–1,000 lines so an observer cannot infer the prefix from response length. Cloudflare’s Validating Leaked Passwords with k-Anonymity calls this a k-anonymity range query: the server never receives the full hash of a password that is not already in the corpus, so it cannot later “unmask” that one query on its own.

An email lookup is a different path. The docs are explicit: putting an email address in the path hands that address to HIBP. The k-anonymity email search sends the first six characters of the email’s SHA-1—not the first five of a password hash. If a ticket says “I checked HIBP,” write down whether you queried a password-hash prefix or an email. The privacy boundary is different, and so is the conclusion.

FastPwd does not call either HIBP API. Password Audit can do a local entropy estimate plus this public high-frequency list. If you need a billion-hash corpus, use HIBP’s official page or an offline copy you host, and open Network yourself to confirm the request line holds only five hex characters. Do not assume “a security tool will query HIBP for you.”

Use Network to confirm the password did not leave

“Not uploaded” on the page is not evidence. A canary string is. The steps are the same family as “did local encryption carry plaintext out,” but the things you watch are the password field and the list file.

  1. Open DevTools Network and turn on Preserve log. Leave the filter empty at first so analytics reports are not hidden.
  2. On the Password Audit page, type a canary such as CanaryPwd-20260902-xK9 and wait for the local compute to finish—about 280 milliseconds after the last keystroke.
  3. Search the request list for that canary. It should not appear on a request line, in a query string, in a body, or in a form field.
  4. You should see a same-origin GET for data/leaked-top10k.txt. Open the response: one public password per line, and your canary should not be among them.
  5. If a site claims it talks to HIBP, look for api.pwnedpasswords.com/range/: the path should hold five hex characters, not plaintext.

Visit analytics can still exist. FastPwd’s audit events push names only—for example “audit started,” “result weak,” or “hit on leaked list”—and do not send the input box as a parameter. Open a report to /tj/matomo.php and search for the canary; it should not match. Closing the tab does not leave this input on a FastPwd server—if it never arrived as business data. That sentence has to rest on the search you just ran, not on “I closed the page.”

If the canary appears in any request, the conclusion flips. Whatever the button said—“local,” “private,” “in-browser”—this check already sent the password out of the tab. Switch tools, or switch to an offline list, and repeat the same steps.

What a hit can support, and what a miss cannot

On a hit, the sentence that belongs in a ticket is: “This string matched the public high-frequency list downloaded with the page (exact / case / trailing digits / leet). On this device it is treated as an extremely common weak password. Change it, and do not reuse it on other sites.” The sentence that does not belong is: “The other party’s server confirmed this is the plaintext from breach X in year Y.” The local list has no incident name and no seen-count—only a rank hint.

On a miss, the defensible sentence is shorter: “No match against the current public high-frequency list and its four variant stages.” You cannot write “never leaked,” “safe to keep,” or “cleaner than HIBP.” A list of just over 800 high-frequency words was never designed to prove safety. Attacker spray dictionaries, a company’s historical passwords, and a long phrase that appeared in one private dump will not be on that page.

Entropy is a third, parallel signal. The page estimates bits from length and character class: ≥ 80 is Very strong, ≥ 60 is Strong, ≥ 40 is Medium, and the rest is Weak. Offline brute force is shown at about 10 billion guesses per second; an online, rate-limited guess is shown at about 1,000 per second. Those numbers compare relative cost. They are not a countdown. Shorter than 8 characters, or a hit on the built-in Top common-weak set, forces Weak. A hit on the public list rewrites the grade to Weak even when entropy is high—because a dictionary attack does not walk the “average brute-force” path.

FAQ

If a password misses the local weak-password list, does that mean it was never breached?

No. A miss only means that, in this tab’s public high-frequency list, exact match, case folding, stripping a trailing 0–999, and common leet did not line up. It does not prove the string never appeared in any breach dump, never appeared in Have I Been Pwned, or is safe to keep reusing.

Does a Have I Been Pwned password check send the plaintext password?

Not if the client follows the official API. A Pwned Passwords range query accepts only the first five characters of a SHA-1 or NTLM hash and returns about 800 suffixes; the full comparison stays on the client. The plaintext and the full hash should not appear on the request. Checking an email is a different API: submitting the address in the path hands that address to the service. Trust the request line you opened in Network, not the button label.

Does FastPwd Password Audit query Have I Been Pwned?

No. It checks the public high-frequency list downloaded with the page. The password you test is not sent as HTTP business data and is not written into analytics. Visit analytics only records event names such as “audit started” or “result weak / medium / strong.” Ready to use, no account, and there is no vault on the site that could store an audit record.

If entropy is high but the list hits, is the password still strong?

On this device, a hit on the public weak-password list forces the grade to Weak. Entropy estimates brute-force cost over a character space. The list answers whether that string already sits in an attacker’s dictionary. The two questions do not cancel each other. NIST SP 800-63B-4 asks verifiers to check a whole-string blocklist of common or compromised passwords, not composition rules or a calendar reminder to rotate.

Walk the steps with a fake password

If you want a page whose compute boundary is written down, open FastPwd’s Password Audit. Ready to use—no signup. Type password or qwerty123 first: you should see a public-list hit forced to Weak. Then type the canary above: it should miss the list, and a Network search should not find that string. You can open the list GET and count the lines; they should line up with “just over 800 high-frequency words” in this article.

After a Weak grade, open the password generator and draw a new string on this device: random mode is 6–128 characters, default 16; shorter than 8 is flagged as weaker. If you must hand the new password to a colleague, switch to Burn-Link: this device encrypts with AES-256-GCM, the server stores ciphertext only, and the key sits after the hash in the link. Do not paste a complete Burn-Link back into any “online checker” box.

The point of the drill is not to prove any one site is “absolutely safe.” It is to give you a comparison you can show a colleague before anyone hits Check: this run uploaded plaintext, sent a hash prefix, or used a short local list; replace on a hit; on a miss, do not write “never leaked.” The same steps work on any “security score” or “breach lookup” extension.

The next time someone pastes a password into a checker, ask three questions. First: did the request carry plaintext or a full hash? Second: did it match about 800 high-frequency words, or did it run an HIBP-style range query? Third: which sentence will the ticket use if there is no hit? Only a check you can repeat is worth putting in your own password standard.

Further reading

To confirm whether the checker page itself sent the original string, run a fuller Network pass with the same canary: How to check if browser encryption never uploaded plaintext. When you must hand a complete secret to another person—not to a checker box—see why the key can sit after the hash, and when that layer fails: Why a URL hash can hold a key, and when that protection fails. Before tickets and logs go into an AI box, compare fields at the source: Before you paste tickets and logs into AI, check which fields leave this machine.