Simple Math Question on the Login Form
Adds a small addition question to wp-login.php that bots fail, without third-party CAPTCHA services or cookies.
Opens WPIDE on
Code
add_action( 'login_form', function () {
$a = wp_rand( 1, 9 );
$b = wp_rand( 1, 9 );
$time = time();
$token = hash_hmac( 'sha256', ( $a + $b ) . '|' . $time, wp_salt( 'nonce' ) );
?>
<p>
<label for="wpide_math"><?php echo esc_html( sprintf( 'What is %d + %d?', $a, $b ) ); ?></label>
<input type="number" name="wpide_math" id="wpide_math" class="input" inputmode="numeric" autocomplete="off" required>
<input type="hidden" name="wpide_math_time" value="<?php echo esc_attr( $time ); ?>">
<input type="hidden" name="wpide_math_token" value="<?php echo esc_attr( $token ); ?>">
</p>
<?php
} );
add_filter( 'authenticate', function ( $user ) {
// Only the wp-login.php form; XML-RPC, REST and other login forms are left alone.
if ( 'wp-login.php' !== ( isset( $GLOBALS['pagenow'] ) ? $GLOBALS['pagenow'] : '' ) || empty( $_POST['log'] ) ) {
return $user;
}
$answer = isset( $_POST['wpide_math'] ) ? (int) $_POST['wpide_math'] : -1;
$time = isset( $_POST['wpide_math_time'] ) ? (int) $_POST['wpide_math_time'] : 0;
$token = isset( $_POST['wpide_math_token'] ) ? sanitize_text_field( wp_unslash( $_POST['wpide_math_token'] ) ) : '';
$valid = $time > time() - HOUR_IN_SECONDS && hash_equals( hash_hmac( 'sha256', $answer . '|' . $time, wp_salt( 'nonce' ) ), $token );
return $valid ? $user : new WP_Error( 'wpide_math', '<strong>Error:</strong> Please answer the math question correctly.' );
}, 25 );
Notes
Custom login forms (shop or membership plugins) do not show the question and are not checked.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.