function UserPasswordResetTest::testResetImpersonation
Same name in other branches
- 9 core/modules/user/tests/src/Functional/UserPasswordResetTest.php \Drupal\Tests\user\Functional\UserPasswordResetTest::testResetImpersonation()
- 8.9.x core/modules/user/tests/src/Functional/UserPasswordResetTest.php \Drupal\Tests\user\Functional\UserPasswordResetTest::testResetImpersonation()
- 11.x core/modules/user/tests/src/Functional/UserPasswordResetTest.php \Drupal\Tests\user\Functional\UserPasswordResetTest::testResetImpersonation()
Make sure that users cannot forge password reset URLs of other users.
File
-
core/
modules/ user/ tests/ src/ Functional/ UserPasswordResetTest.php, line 605
Class
- UserPasswordResetTest
- Ensure that password reset methods work as expected.
Namespace
Drupal\Tests\user\FunctionalCode
public function testResetImpersonation() : void {
// Create two identical user accounts except for the user name. They must
// have the same empty password, so we can't use $this->drupalCreateUser().
$edit = [];
$edit['name'] = $this->randomMachineName();
$edit['mail'] = $edit['name'] . '@example.com';
$edit['status'] = 1;
$user1 = User::create($edit);
$user1->save();
$edit['name'] = $this->randomMachineName();
$user2 = User::create($edit);
$user2->save();
// Unique password hashes are automatically generated, the only way to
// change that is to update it directly in the database.
Database::getConnection()->update('users_field_data')
->fields([
'pass' => NULL,
])
->condition('uid', [
$user1->id(),
$user2->id(),
], 'IN')
->execute();
\Drupal::entityTypeManager()->getStorage('user')
->resetCache();
$user1 = User::load($user1->id());
$user2 = User::load($user2->id());
$this->assertEquals($user2->getPassword(), $user1->getPassword(), 'Both users have the same password hash.');
// The password reset URL must not be valid for the second user when only
// the user ID is changed in the URL.
$reset_url = user_pass_reset_url($user1);
$attack_reset_url = str_replace("user/reset/{$user1->id()}", "user/reset/{$user2->id()}", $reset_url);
$this->drupalGet($attack_reset_url);
// Verify that the invalid password reset page does not show the user name.
$this->assertSession()
->pageTextNotContains($user2->getAccountName());
$this->assertSession()
->addressEquals('user/password');
$this->assertSession()
->pageTextContains('You have tried to use a one-time login link that has either been used or is no longer valid. Request a new one using the form below.');
$this->drupalGet($attack_reset_url . '/login');
// Verify that the invalid password reset page does not show the user name.
$this->assertSession()
->pageTextNotContains($user2->getAccountName());
$this->assertSession()
->addressEquals('user/password');
$this->assertSession()
->pageTextContains('You have tried to use a one-time login link that has either been used or is no longer valid. Request a new one using the form below.');
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.