PluginProbe
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… / 3.0.0
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… v3.0.0
3.0.0 2.11.12 2.11.11 2.11.10 2.11.9 2.11.7 2.11.8 2.11.6 2.11.5 2.11.4 2.11.3 2.11.1 2.11.2 2.11.0 2.10.5 2.10.4 2.10.3 2.10.2 2.10.1 2.10.0 2.9.9 2.9.8 2.9.6 2.9.7 2.9.5 All 88 releases
← All changes | includes/class-two-factor-email.php +22 -5 2.11.103.0.0 View file →
@@ -349,12 +349,24 @@
349 349
350 350 $code = isset( $_POST['vigilante_2fa_code'] ) ? sanitize_text_field( wp_unslash( $_POST['vigilante_2fa_code'] ) ) : '';
351 351 $remember_device = ! empty( $_POST['vigilante_2fa_remember'] );
352 352
353 + // Read before verifying: running out of attempts clears the pending
354 + // session inside verify_code(), and the redirect_to of the original
355 + // login lives there.
356 + $redirect_to = $this->pending_login_redirect();
357 +
353 358 // Verify code
354 359 $result = $this->verify_code( $user_id, $code );
355 360
356 361 if ( is_wp_error( $result ) ) {
362 + // Out of attempts: the session is gone, so the form that would show
363 + // this message is not painted any more. Say it on the login screen
364 + // instead of bouncing the visitor there with no explanation.
365 + if ( 'max_attempts' === $result->get_error_code() ) {
366 + $this->redirect_to_login_with_notice( 'attempts' );
367 + }
368 +
357 369 // Store error for display
358 370 set_transient( 'vigilante_2fa_error_' . $user_id, $result->get_error_message(), 60 );
359 371
360 372 // Redirect back to login
@@ -380,11 +392,11 @@
380 392 wp_set_auth_cookie( $user_id, false );
381 393 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- wp_login is a WordPress core hook that must be fired on login.
382 394 do_action( 'wp_login', $user->user_login, $user );
383 395
384 - // Redirect to admin dashboard (always use admin_url to avoid issues with popups,
385 - // malformed URLs, or query parameters that could cause problems)
386 - wp_safe_redirect( admin_url() );
396 + // Where the login was headed, or the dashboard. wp_validate_redirect()
397 + // has already dropped anything off this site (pending_login_redirect()).
398 + wp_safe_redirect( $redirect_to );
387 399 exit;
388 400 }
389 401
390 402 /**
@@ -394,8 +406,13 @@
394 406 * @param string $code Submitted code.
395 407 * @return true|WP_Error
396 408 */
397 409 private function verify_code( $user_id, $code ) {
410 + // Mail clients and password managers show the code in groups and paste
411 + // it with the separator. Until 2.11.12 that reached wp_hash() as typed
412 + // and every correct code pasted that way came back "invalid".
413 + $code = preg_replace( '/\D/', '', (string) $code );
414 +
398 415 $stored = $this->database->get_2fa_code( $user_id );
399 416 $user = get_user_by( 'ID', $user_id );
400 417
401 418 if ( ! $stored ) {
@@ -564,10 +581,10 @@
564 581 name="vigilante_2fa_code"
565 582 id="vigilante_2fa_code"
566 583 class="input"
567 584 size="6"
568 - maxlength="6"
569 - pattern="[0-9]{6}"
585 + maxlength="20"
586 + pattern="[0-9 -]{6,20}"
570 587 inputmode="numeric"
571 588 autocomplete="one-time-code"
572 589 autofocus
573 590 required>