Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed : A password change should not destroy a user's session data #6950

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/wp-includes/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -2780,8 +2780,6 @@ function wp_update_user( $userdata ) {
$current_user = wp_get_current_user();
if ( $current_user->ID === $user_id ) {
if ( isset( $plaintext_pass ) ) {
wp_clear_auth_cookie();

/*
* Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
* If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
Expand All @@ -2790,13 +2788,20 @@ function wp_update_user( $userdata ) {
/** This filter is documented in wp-includes/pluggable.php */
$default_cookie_life = apply_filters( 'auth_cookie_expiration', ( 2 * DAY_IN_SECONDS ), $user_id, false );

wp_clear_auth_cookie();

$remember = false;
$token = '';

if ( false !== $logged_in_cookie ) {
$token = $logged_in_cookie['token'];
}

if ( false !== $logged_in_cookie && ( (int) $logged_in_cookie['expiration'] - time() ) > $default_cookie_life ) {
$remember = true;
}

wp_set_auth_cookie( $user_id, $remember );
wp_set_auth_cookie( $user_id, $remember, '', $token );
}
}

Expand Down
72 changes: 72 additions & 0 deletions tests/phpunit/tests/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,37 @@ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
public function set_up() {
parent::set_up();

add_action( 'set_auth_cookie', array( $this, 'action_set_auth_cookie' ), 10, 6 );
add_action( 'set_logged_in_cookie', array( $this, 'action_set_logged_in_cookie' ), 10 );
add_action( 'clear_auth_cookie', array( $this, 'action_clear_auth_cookie' ) );

$_COOKIE = array();

$this->author = clone self::$_author;
}

final public function action_set_auth_cookie(
string $cookie,
int $expire,
int $expiration,
int $user_id,
string $scheme,
string $token
): void {
$_COOKIE[ SECURE_AUTH_COOKIE ] = $cookie;
$_COOKIE[ AUTH_COOKIE ] = $cookie;
}

final public function action_set_logged_in_cookie( string $cookie ): void {
$_COOKIE[ LOGGED_IN_COOKIE ] = $cookie;
}

final public function action_clear_auth_cookie(): void {
unset( $_COOKIE[ LOGGED_IN_COOKIE ] );
unset( $_COOKIE[ SECURE_AUTH_COOKIE ] );
unset( $_COOKIE[ AUTH_COOKIE ] );
}

public function test_get_users_of_blog() {
// Add one of each user role.
$nusers = array(
Expand Down Expand Up @@ -1122,6 +1150,50 @@ public function test_changing_password_invalidates_password_reset_key() {
$this->assertEmpty( $user->user_activation_key );
}

/**
* @ticket 61366
* @dataProvider data_remember_user
*/
public function test_changing_own_password_retains_current_session( bool $remember ) {
$user = $this->author;
$manager = WP_Session_Tokens::get_instance( $user->ID );
$expiry = $remember ? ( 2 * WEEK_IN_SECONDS ) : ( 2 * DAY_IN_SECONDS );
$token = $manager->create( time() + $expiry );
$pass = $user->user_pass;

wp_set_current_user( $user->ID );
wp_set_auth_cookie( $user->ID, $remember, '', $token );

$cookie = $_COOKIE[ AUTH_COOKIE ];
$userdata = array(
'ID' => $user->ID,
'user_pass' => 'my_new_password',
);
$updated = wp_update_user( $userdata, $manager );
$parsed = wp_parse_auth_cookie();

// Check the prerequisites:
$this->assertNotWPError( $updated );
$this->assertNotSame( $pass, get_userdata( $user->ID )->user_pass );

// Check the session token:
$this->assertSame( $token, $parsed['token'] );
$this->assertCount( 1, $manager->get_all() );

// Check that the newly set auth cookie is valid:
$this->assertSame( $user->ID, wp_validate_auth_cookie() );

// Check that, despite the session token reuse, the old auth cookie should now be invalid because the password changed:
$this->assertFalse( wp_validate_auth_cookie( $cookie ) );
}

public function data_remember_user() {
return array(
array( true ),
array( false ),
);
}

public function test_search_users_login() {
$users = get_users(
array(
Expand Down
Loading