Recently, I released my first-ever WordPress plugin, Forbid Pwned Passwords, to the WordPress plugin repository. Despite being a relatively small project, I’m proud of my little contribution to the WordPress community.
The plugin leverages the Have I Been Pwned API to compare newly reset passwords with a database of known breached credentials. This is an effective measure against credential stuffing attacks, as well as providing affected users with information intended to help them understand the risks associated with password reuse.
On the technical side, FPP hooks into the “validate_password_reset” and “user_profile_update_errors” actions. As part of the password reset validation, a hash of the new password is taken, and the first five characters of this hash are submitted to the API. A response containing a list of potentially matching hashes is returned, and the final comparison is completed locally by the plugin. This has the advantage of anonymizing the process of checking these passwords, and means that no passwords or otherwise sensitive data are ever sent to a third party.
Once activated, the plugin is all but invisible until a password reset is attempted and a compromised password is submitted:
When the new password is hashed and the first five characters of the hash are sent to the API, we receive a response containing potentially matching suffixes and their corresponding incidence counts.
If any of the returned suffixes match the end of the hash of the user’s submitted password, a WP_Error object is generated and returned from the working action, preventing the password from being used and throwing an informative error message.
When my current lack of free time subsides, I plan to implement some quality of life tweaks in future versions of FPP. These include user-role specific checks, attempt logging, and customizable error messages.