WordPress password reset – why post rp_key?

I’m developing a plugin and after reading through wp-login.php, I can’t seem to work out why some things are done the way they are.

Why does WordPress hide the reset password key from the URL?

After reading this question, it appears that I am not the only one. However, in additional to the question linked, I don’t understand why rp_key is a hidden field in the reset password form when it’s already stored in a cookie?

<input type=”hidden” name=”rp_key” value=”<?php echo esc_attr( $rp_key ); ?>” />

rp_key is exploded from the cookie and added to the form.

if ( isset( $_COOKIE[ $rp_cookie ] ) && 0 < strpos( $_COOKIE[ $rp_cookie ], ‘:’ ) ) {
list( $rp_login, $rp_key ) = explode( ‘:’, wp_unslash( $_COOKIE[ $rp_cookie ] ), 2 );
$user = check_password_reset_key( $rp_key, $rp_login );
if ( isset( $_POST[‘pass1’] ) && ! hash_equals( $rp_key, $_POST[‘rp_key’] ) ) {
$user = false;
}
} else {
$user = false;
}

This is the line that’s really getting me:

if ( isset( $_POST[‘pass1’] ) && ! hash_equals( $rp_key, $_POST[‘rp_key’] ) ) {

This line appears to be, if the form has been submitted and the key from the cookie is different to posted key, error.

I don’t understand why this line is not redundant? The previous line has already checked that the key matches the user, so why do we need to post the key at all?

I can’t think of any situation where this line returns false and the previous line had not already returned error, making this line redundant.

The only slightly logical reason I can think of is to ensure that the request came from the actual form, however this is easily circumvented by just posted the key. It seems that if this was the goal, then a nonce should be used. Which in turn begs the question, why is there no nonce?

Read more here:: WordPress password reset – why post rp_key?

Leave a Reply

Your email address will not be published. Required fields are marked *