Have I Been Pwned
A plugin to check if a password has been compromised
The Have I Been Pwned plugin helps protect user accounts by preventing the use of passwords that have been exposed in known data breaches. It uses the Have I Been Pwned API to check if a password has been compromised.
Installation
Add the plugin to your auth config
import { betterAuth } from "better-auth"
import { haveIBeenPwned } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
haveIBeenPwned()
]
})Usage
When a user attempts to create an account or update their password with a compromised password, they'll receive the following default error:
{
"code": "PASSWORD_COMPROMISED",
"message": "The password you entered has been compromised. Please choose a different password."
}Custom password flows
Use isPasswordCompromised to check passwords in server-side flows that do not use Better Auth endpoints.
import { isPasswordCompromised } from "better-auth/plugins/haveibeenpwned"
const compromised = await isPasswordCompromised(password)
if (compromised) {
throw new Error("Please choose a password that has not been compromised")
}The function only sends the first five characters of the password's SHA-1 hash to Have I Been Pwned. It throws an APIError if the service cannot complete the check.
Options
enabled
Enable or disable password checks against the HIBP database. Useful for skipping checks in development or testing without removing the plugin. Defaults to true.
import { betterAuth } from "better-auth"
import { haveIBeenPwned } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
haveIBeenPwned({
enabled: process.env.NODE_ENV === 'production'
})
]
})customPasswordCompromisedMessage
Customize the error message shown when a compromised password is detected.
import { betterAuth } from "better-auth"
import { haveIBeenPwned } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
haveIBeenPwned({
customPasswordCompromisedMessage: "Please choose a more secure password."
})
]
})Security Notes
- Only the first 5 characters of the password hash are sent to the API
- The full password is never transmitted
- Provides an additional layer of account security