Admins know it’s key that WordPress users have secure passwords to keep web security watertight. But do you know if your WordPress users are accessing your CMS with insecure ‘pwned’ passwords? And do you know the risk?
What is a pwned password?
Pwned passwords are over seven billion real-world passwords that have been exposed in data breaches. This exposure makes them unsuitable for use as they’re at much greater risk of being used to take over other accounts. They’re searchable online at the Have I Been Pwned database.
What’s the risk?
People using pwned passwords can pose a serious risk to your cybersecurity. When hackers undertake a brute force attack – using passwords to take personal information or spend users’ hard earned money through your site – it’s usually the site owner/developer who gets the blame.
The National Institute of Standards and Technology has issued guidelines for federal agencies implementing digital identity services, which state:
When processing requests to establish and change memorised secrets, verifiers SHALL compare the prospective secrets against a list that contains values known to be commonly-used, expected, or compromised. For example…NIST Digital Identity Guidelines
* Passwords obtained from previous breach corpuses
If federal agencies are doing it, we recommend you do too.
How do I check our WordPress site isn’t using any pwned passwords?
To help reduce such incidents, we have created a WordPress plugin to prevent users of WordPress and WooCommerce from reusing passwords listed in the haveibeenpwned.com database.
Explain how it works like I’m five
- Troy Hunt, a well-known security expert, collected over seven billion pwned passwords from previous security breaches
- Pwned passwords are stored as SHA-1 hashes on haveibeenpwned.com
- Whenever WordPress/WooCommerce users attempt to change their passwords, our plugin hashes the user’s password
- It takes the first five characters from the hash
- The plugin then asks haveibeenpwned.com to cross check for all pwned passwords with the same first five hash characters
- It then checks how many times the password appears on the haveibeenpwned.com database
- It will then disallow the password change if it has been pwned
How to forbid WordPress users to use pwned passwords
- Download and install Disallow Pwned Password from WordPress plugin repository
- Activate and forget it!
Once activated, Disallow Pwned Passwords automatically intercepts when:
- creating new users on
- changing other users’ passwords on
- changing your password on
- new user registration on
If the new password is found in the haveibeenpwned.com database, the plugin rejects the change.
How to prevent WooCommerce users from using breached passwords
WooCommerce displays personal identifiable information (PII), e.g: name, phone number, address, etc, to returning customers. It’s important to PII from credential stuffing. Therefore, Disallow Pwned Passwords provides built-in support for WooCommerce.
If WooCommerce is activated, this plugin automatically rejects pwned password when:
- resetting password on Home » My account » Lost password
- changing password on Home » My account » Account details
- new user registration on Home » My account
- new user registration during checkout
Did you just send all the passwords to someone else?
No. User passwords never leave your server, not even in hashed form.
How do you compare user passwords with the pwned ones?
To securely compare user passwords against the ones in the
- user passwords never leave WordPress web servers
- the haveibeenpwned.com database provides information about a password without knowing which password it is
Junade Ali from Cloudflare comes up with a solution utilising a mathematical property known as k-Anonymity and applies it to password hashes in the form of range queries. (See: Validating Leaked Passwords with k-Anonymity)
Let’s see a real world example:
- User wants to change his password to [email protected]
- Disallow Pwned Passwords hashes [email protected] into 21BD12DC183F740EE76F27B78EB39C8AD972A757
- The plugin takes the first five characters from the hash, i.e: 21BD1
- The plugin retrieves all breached passwords and their pwned count with the same hash prefix:
- (21BD1) 0018A45C4D1DEF81644B54AB7F969B88D65:1 (password lauragpe)
- (21BD1) 00D4F6E8FA6EECAD2A3AA415EEC418D38EC:2 (password alexguo029)
- (21BD1) 011053FD0102E94D6AE2F8B83D76FAF94F6:1 (password BDnd9102)
- (21BD1) 2DC183F740EE76F27B78EB39C8AD972A757:47205 (password [email protected])
- Within the WordPress web server, we find the pwned count (e.g: 47205) by comparing the hash suffix
- The plugin rejects the change and displays the error message to the user
Curious users can learn more from:
- Have I Been Pwned’s FAQs
- Why SHA-1 was chosen in the Pwned Passwords
- I’ve [Troy Hunt] Just Launched “Pwned Passwords” V2 With Half a Billion Passwords for Download
- Validating Leaked Passwords with k-Anonymity
Can strong passwords be pwned?
Yes. Even long passwords like correct horse battery staple have been pwned.
How to choose a strong password
- The only secure password is the one you can’t remember
- How to choose a good Master Password
- Why Secure Passwords Need Length Over Complexity
I have installed this plugin. Does it mean my WordPress site is unhackable?
No website is unhackable.
To have a secure WordPress site, you have to keep all these up-to-date:
- WordPress core
- This plugin
- All other WordPress themes and plugins
- Everything on the server
- Other security practices
- Your mindset
Besides Disallow Pwned Passwords, we strongly recommended these plugins as well:
- WP Password Argon Two – Securely store WordPress user passwords in a database with Argon2i hashing and SHA-512 HMAC using PHP’s native functions
- WP Cloudflare Guard – Connect WordPress with the Cloudflare firewall to protect your WordPress site at
DNSlevel. This allows you to automatically create firewall rules to block dangerous IPs
- Two-Factor – This adds Two-Factor authentication to WordPress
bcrypt– Replace WP’s outdated and insecure MD5-based password hashing with the modern and secure bcryptalgorithm