This issue has been approved for public discussion by the Drupal Security Team.
Problem/Motivation
The IP address blocking system works fine, but if the reset password for the same account is made from a different IP address, the user is still able to do the same number of attempts until the new IP address gets blocked.
In the validateForm of UserPasswordForm, these 3 lines currently don't do anything, since a simple return in validateForm doesn't trigger any error.
if (!$this->flood->isAllowed('user.password_request_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
return;
}
The setError has been removed as part of https://www.drupal.org/node/1521996 which ultimately changed the behaviour and left redundant code (as stated before, the lines above don't do anything). And currently there is no Change Request to put the behaviour described here https://www.drupal.org/node/3085704 back in place.
Steps to reproduce
1. Go to the reset password form
2. Attempt to reset the password for a given account 5 times (ip_limit changed to 5 for testing purposes)
3. After these 5 attempts, the "IP blocked" error message appears
4. Change the IP address (via VPN for instance)
5. Do a new attempt on the same account
6. The same amount of attempts can be done before getting the new IP blocked
Proposed resolution
The account should be appropriately blocked according to the user_limit value. In our example, the account should be blocked at the same time as the first IP address being blocked, since it is set by default to 5.
- Put back the message but with a more generic sentence, so it is unclear if an account exists or not.
if (!$this->flood->isAllowed('user.password_request_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
$form_state->setErrorByName('name', $this->t('Too many password recovery requests. Try again later or contact the site administrator.'));
return;
}