Skip to content

Tidy: don't skip strong-password validation for whitespace-only / "0" input#233

Open
dknauss wants to merge 1 commit into
10up:developfrom
dknauss:fix/whitespace-password-policy-bypass
Open

Tidy: don't skip strong-password validation for whitespace-only / "0" input#233
dknauss wants to merge 1 commit into
10up:developfrom
dknauss:fix/whitespace-password-policy-bypass

Conversation

@dknauss

@dknauss dknauss commented Jul 8, 2026

Copy link
Copy Markdown

Summary

Passwords::validate_strong_password() decides whether a password change is present using trim( $_POST['pass1'] ). That treats an all-whitespace value (" ") — and, because trim()'s result is used as a boolean, a value of "0" — as "no password set", so the function returns early and skips its length / zxcvbn / Have I Been Pwned checks for those inputs.

This is harmless in practice — WordPress core already rejects a whitespace-only password on every path, so one can't actually be set or used through the UI:

  • edit_user() trims pass1 and only saves if ( ! empty( $pass1 ) )" " becomes a no-op change.
  • The reset-password form errors "The password cannot be a space or all spaces." before reset_password() is called.
  • At login, wp_authenticate() trims the entry and wp_authenticate_username_password() rejects an empty password.

So this isn't a policy bypass — it's a small correctness issue: the blank-field test should key off an empty field, not trim(), so the plugin's own checks don't silently skip for whitespace-only / "0" input.

Fix

-$password = ( isset( $_POST['pass1'] ) && trim( $_POST['pass1'] ) ) ? sanitize_text_field( $_POST['pass1'] ) : false;
+$password = ( isset( $_POST['pass1'] ) && '' !== $_POST['pass1'] ) ? sanitize_text_field( $_POST['pass1'] ) : false;

Only a genuinely empty field means "no change". Legitimate password changes are unaffected.

validate_strong_password() detects an empty/unchanged password field with
`trim( $_POST['pass1'] )`. An all-whitespace value (e.g. "   ") trims to '' and
is treated as "no password set", so the function returns early and skips the
length, zxcvbn, and Have I Been Pwned checks — while WordPress still saves the
whitespace password. A user under an enforced strong-password policy can defeat
it this way. (The same early-return also fires for a password of "0", which is
falsy after trim.)

Only a genuinely empty field means "no change", so gate on the string being
non-empty instead of on trim().
@dknauss dknauss changed the title Fix: whitespace-only passwords bypass the strong-password policy Tidy: don't skip strong-password validation for whitespace-only / "0" input Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant