Length, blocklists & current NIST guidance

Password rules that help

Lesson 9 of 20 · 11 min · Module 3: Passwords and sessions

Old password rules, such as one capital letter, one digit, one symbol and a new password every 90 days, mostly produce Passw0rd! and frustrated people. Current guidance asks for length instead, and blocks the passwords attackers try first.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Apply current password guidance
  • Count characters correctly, including Unicode
  • Block common passwords and personal details

The idea

NIST SP 800-63B, revised in 2025, asks for at least 15 characters when a password is the only way to sign in, and at least 8 when it is combined with multi-factor authentication. Allow at least 64 characters, accept spaces and every Unicode character, and refuse passwords that appear on a list of common or breached passwords or that contain details such as the username or the site’s name. Do not demand particular kinds of characters, and do not force regular changes.

const length = [...'mère noël'].length; // 9 characters
const common = ['password', 'qwerty'];
console.log(length, common.includes('Password'.toLowerCase()));

01Length beats complexity

Every extra character multiplies the number of guesses an attacker needs. A rule like “one digit and one symbol” mostly turns password into Password1!, which every cracking tool tries early.

02Block what attackers try first

Attackers start with lists of leaked and popular passwords. Refusing those, and passwords that contain the username or the site’s name, removes the guesses that succeed most often. Explain the refusal in plain words and suggest a long sentence instead.

03Count characters, not code units

JavaScript strings count UTF-16 code units, so an emoji such as 🔒 has a length of 2. Spreading the string into an array counts real characters.

console.log('🔒'.length, [...'🔒'].length);
Output
2 1

Your turn

Write checkPassword(password, { username = '', mfa = false } = {}). Count characters with [...password].length and return, in this order, the codes that apply: too-short (fewer than 15 characters, or 8 with mfa); too-long (more than 64); common (the password, in lowercase, is in COMMON); contains-name (the lowercase password contains the lowercase username of at least 3 characters, or codetemper). Return an empty array for a good password.

What the checks look for

  • Long passwords pass and short ones do not
  • With multi-factor sign-in, 8 characters are enough
  • Common passwords are refused in any capitalisation
  • Up to 64 characters are accepted
  • Spaces and every language count, character by character
  • The username and the site name are refused
  • The form explains what to change
Try it in the editor →

Take this with you

Ask for length, block common choices, and welcome every character.

Go a little further

Add a Show password button that switches the field between type="password" and type="text" and keeps its aria-pressed state up to date.

Learn Web Security Foundations for free

20 short lessons with real code and instant checks.

See the whole course →