apps/docs/content/guides/auth/password-security.mdx
A password is more secure if it is harder to guess or brute-force. In theory, a password is harder to guess if it is longer. It is also harder to guess if it uses a larger set of characters (for example, digits, lowercase and uppercase letters, and symbols).
This table shows the minimum number of guesses that need to be tried to access a user's account:
| Required characters | Length | Guesses |
|---|---|---|
| Digits only | 8 | ~ 2<sup>27</sup> |
| Digits and letters | 8 | ~ 2<sup>41</sup> |
| Digits, lower and uppercase letters | 8 | ~ 2<sup>48</sup> |
| Digits, lower and uppercase letters, symbols | 8 | ~ 2<sup>52</sup> |
In reality though, passwords are not always generated at random. They often contain variations of names, words, dates, and common phrases. Malicious actors can use these properties to guess a password in fewer attempts.
There are hundreds of millions (and growing!) known passwords out there. Malicious actors can use these lists of leaked passwords to automate login attempts (known as credential stuffing) and steal or access sensitive user data.
To help protect your users, Supabase Auth allows you fine-grained control over the strength of the passwords used on your project. You can configure these in your project's Auth settings:
!@#$%^&*()_+-=[]{};'\:"|<>?,./`~Leaked password protection is available on the Pro Plan and above.
</Admonition>Users will need to be recently logged in to change their password without requiring reauthentication. (A user is considered recently logged in if the session was created within the last 24 hours.) If disabled, a user can change their password at any time.
When enabled, a nonce will be sent to the user and this nonce must be validated before the a password change can occur. This can be triggered with the reauthenticate() API call.
const { error } = await supabase.auth.reauthenticate()
...
// send the nonce provided by the user with the password change
const { data, error } = await supabase.auth.updateUser({
email: '[email protected]',
nonce: `${nonce}`,
password: "new_super_strong_password"
})
Enforce that users supply their current password when trying to change the password. When enabled, the password change request will validate that the current password is correct before updating the user's password.
const { data, error } = await supabase.auth.updateUser({
email: '[email protected]',
current_password: "correct_current_password",
password: "new_super_strong_password"
})
In addition to choosing suitable password strength settings and preventing the use of leaked passwords, consider asking your users to:
Supabase Auth uses bcrypt, a strong password hashing function, to store hashes of users' passwords. Only hashed passwords are stored. You cannot impersonate a user with the password hash. Each hash is accompanied by a randomly generated salt parameter for extra security.
The hash is stored in the encrypted_password column of the auth.users table. The column's name is a misnomer (cryptographic hashing is not encryption), but is kept for backward compatibility.
Existing users can still sign in with their current password even if it doesn't meet the new, strengthened password requirements. However, if their password falls short of these updated standards, they will encounter a WeakPasswordError during the signInWithPassword process, explaining why it's considered weak. This change is also applicable to new users and existing users changing their passwords, ensuring everyone adheres to the enhanced security standards.