Opened 7 weeks ago
Last modified 6 weeks ago
#65144 new defect (bug)
Passwords: trim() asymmetry between wp_hash_password() and wp_check_password() introduced in 6.8
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 6.8 |
| Component: | General | Keywords: | has-patch |
| Focuses: | Cc: |
Description
wp_hash_password() and wp_check_password() handle whitespace
inconsistently in the bcrypt path introduced in 6.8.
wp_hash_password() (pluggable.php line 2809):
hash_hmac('sha384', trim($password), 'wp-sha384', true)
wp_check_password() (pluggable.php line 2858):
hash_hmac('sha384', $password, 'wp-sha384', true)
The hashing function trims leading and trailing whitespace before
hashing. The verification function does not. This means a password
set with leading or trailing whitespace will hash as the trimmed
value but verify against the untrimmed value, producing a mismatch
and locking the user out.
The default login path (wp_authenticate) trims upstream, so normal
logins are not affected. However any code that calls wp_check_password()
directly without prior trimming is broken — this includes plugins,
REST API handlers, and custom authentication flows.
A similar issue was fixed in ticket #34889 but did not carry forward
to the new bcrypt code path added in 6.8.
Expected behavior: wp_check_password() should trim the password before
hashing for verification, mirroring wp_hash_password().
Suggested fix: change line 2858 in pluggable.php from:
hash_hmac('sha384', $password, 'wp-sha384', true)
to:
hash_hmac('sha384', trim($password), 'wp-sha384', true)
Change History (4)
This ticket was mentioned in PR #11675 on WordPress/wordpress-develop by @hbhalodia.
7 weeks ago
#2
- Keywords has-patch added
Trac ticket: https://core.trac.wordpress.org/ticket/65144
- Update function,
wp_check_password, to include thetrim()while checking the password created usingwp_hash_password.
## Use of AI Tools
- None
@darshitrajyaguru97 commented on PR #11675:
7 weeks ago
#3
I’ve reviewed the PR and confirmed the issue locally.
The fix looks correct for the bcrypt ($wp) path and aligns with wp_hash_password() behavior.
A couple of points to consider:
- The PR description could include more context about the mismatch and its impact on direct wp_check_password() usage.
- Are there PHPUnit tests covering leading/trailing whitespace cases? Adding those would help prevent regressions.
- CI checks appear incomplete (PHPUnit cancelled). It may be worth ensuring all tests pass before review.
Also, should trimming be limited to the $wp path only, or applied consistently across all password verification paths?
#4
@
6 weeks ago
The asymmetry is in the bcrypt path only. wp_hash_password()
calls trim() before hash_hmac() but wp_check_password() does not,
causing login failures for passwords with leading/trailing
whitespace when wp_check_password() is called directly.
Fix: add trim() to the password argument in wp_check_password()
to match wp_hash_password().
Patch submitted via PR: https://github.com/Anny0007/AV-wordpress-develop/pull/2
Please update keywords to has-patch.
Hi @mkultraware, Thanks for the ticket. I can verify indeed it's an issue.
For a quick check for the usecase, we can use the below snipped as a plugin and test it out.
add_action( 'init', function() { $hashed = wp_hash_password( ' password-to-hash. ' ); $to_check = wp_check_password( ' password-to-hash. ', $hashed ); var_dump( $to_check ); wp_die(); });The output would be
bool(false), instead it should bebool(true). This is because,wp_check_passwordis not handling the leading/trailing spaces as howwp_hash_passworddoes while hashing the password.To handle is properly for all the usecases, Instead of just adding trim to line
2858, we should add the trim to all passwords IMO, but sincewp_hash_passwordadds a unique prefix, then wp_check_password will satisfy the condition on line,2856: elseif ( str_starts_with( $hash, '$wp' ) ) {, So for adding a patch currently, I am adding it specifically for the if condition, but we can handle that in PR review and update as needed.Thanks,