diff --git a/includes/admin/core/class-admin-settings.php b/includes/admin/core/class-admin-settings.php index a37ddbee..50f8c98a 100644 --- a/includes/admin/core/class-admin-settings.php +++ b/includes/admin/core/class-admin-settings.php @@ -759,6 +759,9 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) { 'reset_password_limit_number' => array( 'sanitize' => 'absint', ), + 'change_password_request_limit' => array( + 'sanitize' => 'bool', + ), 'blocked_emails' => array( 'sanitize' => 'textarea', ), @@ -1285,6 +1288,12 @@ if ( ! class_exists( 'um\admin\core\Admin_Settings' ) ) { 'conditional' => array( 'enable_reset_password_limit', '=', 1 ), 'size' => 'small', ), + array( + 'id' => 'change_password_request_limit', + 'type' => 'checkbox', + 'label' => __( 'Change Password request limit', 'ultimate-member' ), + 'tooltip' => __( 'This option adds rate limit when submitting the change password form in the Account page. Users are only allowed to submit 1 request per 30 minutes to prevent from any brute-force attacks or password guessing with the form.', 'ultimate-member' ), + ), array( 'id' => 'blocked_emails', 'type' => 'textarea', diff --git a/includes/class-config.php b/includes/class-config.php index 5938a261..296286d5 100644 --- a/includes/class-config.php +++ b/includes/class-config.php @@ -553,6 +553,7 @@ if ( ! class_exists( 'um\Config' ) ) { 'restricted_block_message' => '', 'enable_reset_password_limit' => 1, 'reset_password_limit_number' => 3, + 'change_password_request_limit' => false, 'blocked_emails' => '', 'blocked_words' => 'admin' . "\r\n" . 'administrator' . "\r\n" . 'webmaster' . "\r\n" . 'support' . "\r\n" . 'staff', 'allowed_choice_callbacks' => '', diff --git a/includes/core/class-password.php b/includes/core/class-password.php index 9b18caa7..92e88479 100644 --- a/includes/core/class-password.php +++ b/includes/core/class-password.php @@ -526,6 +526,18 @@ if ( ! class_exists( 'um\core\Password' ) ) { } } + if ( ! empty( $args['user_password'] ) && UM()->options()->get( 'change_password_request_limit' ) && is_user_logged_in() ) { + $transient_id = '_um_change_password_rate_limit__' . um_user( 'ID' ); + $last_request = get_transient( $transient_id ); + $request_limit_time = apply_filters( 'um_change_password_attempt_limit_interval', 30 * MINUTE_IN_SECONDS ); + if ( ! $last_request ) { + set_transient( $transient_id, time(), $request_limit_time ); + } else { + UM()->form()->add_error( 'user_password', __( 'Unable to change password because of password change limit. Please try again later.', 'ultimate-member' ) ); + return; + } + } + if ( isset( $args['user_password'] ) && empty( $args['user_password'] ) ) { UM()->form()->add_error( 'user_password', __( 'You must enter a new password', 'ultimate-member' ) ); }