Skip to content

Commit

Permalink
Hash the login nonce for storage to avoid leaking it via DB access (#453
Browse files Browse the repository at this point in the history
)
  • Loading branch information
kasparsd authored Sep 8, 2022
1 parent 392f78e commit f3232d9
Show file tree
Hide file tree
Showing 7 changed files with 20,215 additions and 321 deletions.
40 changes: 30 additions & 10 deletions class-two-factor-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ public static function backup_2fa() {
}

if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
wp_safe_redirect( get_bloginfo( 'url' ) );
wp_safe_redirect( home_url() );
exit;
}

Expand Down Expand Up @@ -728,6 +728,17 @@ public static function login_url( $params = array(), $scheme = 'login' ) {
return add_query_arg( $params, site_url( 'wp-login.php', $scheme ) );
}

/**
* Get the hash of a nonce for storage and comparison.
*
* @param string $nonce Nonce value to be hashed.
*
* @return string
*/
protected static function hash_login_nonce( $nonce ) {
return wp_hash( $nonce, 'nonce' );
}

/**
* Create the login nonce.
*
Expand All @@ -737,15 +748,21 @@ public static function login_url( $params = array(), $scheme = 'login' ) {
* @return array
*/
public static function create_login_nonce( $user_id ) {
$login_nonce = array();
$login_nonce = array(
'expiration' => time() + HOUR_IN_SECONDS,
);

try {
$login_nonce['key'] = bin2hex( random_bytes( 32 ) );
} catch ( Exception $ex ) {
$login_nonce['key'] = wp_hash( $user_id . wp_rand() . microtime(), 'nonce' );
}
$login_nonce['expiration'] = time() + HOUR_IN_SECONDS;

if ( ! update_user_meta( $user_id, self::USER_META_NONCE_KEY, $login_nonce ) ) {
// Store the nonce hashed to avoid leaking it via database access.
$login_nonce_stored = $login_nonce;
$login_nonce_stored['key'] = self::hash_login_nonce( $login_nonce['key'] );

if ( ! update_user_meta( $user_id, self::USER_META_NONCE_KEY, $login_nonce_stored ) ) {
return false;
}

Expand Down Expand Up @@ -775,16 +792,19 @@ public static function delete_login_nonce( $user_id ) {
*/
public static function verify_login_nonce( $user_id, $nonce ) {
$login_nonce = get_user_meta( $user_id, self::USER_META_NONCE_KEY, true );
if ( ! $login_nonce ) {

if ( ! $login_nonce || empty( $login_nonce['key'] ) || empty( $login_nonce['expiration'] ) ) {
return false;
}

if ( $nonce !== $login_nonce['key'] || time() > $login_nonce['expiration'] ) {
self::delete_login_nonce( $user_id );
return false;
if ( hash_equals( $login_nonce['key'], self::hash_login_nonce( $nonce ) ) && time() < $login_nonce['expiration'] ) {
return true;
}

return true;
// Require a fresh nonce if verification fails.
self::delete_login_nonce( $user_id );

return false;
}

/**
Expand All @@ -806,7 +826,7 @@ public static function login_form_validate_2fa() {
}

if ( true !== self::verify_login_nonce( $user->ID, $nonce ) ) {
wp_safe_redirect( get_bloginfo( 'url' ) );
wp_safe_redirect( home_url() );
exit;
}

Expand Down
25 changes: 15 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,32 @@
"issues": "https://github.com/WordPress/two-factor/issues"
},
"config": {
"sort-packages": true,
"platform": {
"php": "5.6.20"
},
"allow-plugins": {
"roots/wordpress-core-installer": true,
"dealerdirect/phpcodesniffer-composer-installer": true
"dealerdirect/phpcodesniffer-composer-installer": true,
"roots/wordpress-core-installer": true
}
},
"extra": {
"wordpress-install-dir": "wordpress"
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.4",
"wp-coding-standards/wpcs": "^2.3",
"roots/wordpress": "^5.9",
"wp-phpunit/wp-phpunit": "^5.9",
"phpunit/phpunit": "^5",
"yoast/phpunit-polyfills": "^1.0",
"phpcompatibility/phpcompatibility-wp": "^2.1",
"automattic/vipwpcs": "^2.3",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"automattic/vipwpcs": "^2.3"
"php-coveralls/php-coveralls": "^2.5",
"phpcompatibility/phpcompatibility-wp": "^2.1",
"phpunit/phpunit": "^5",
"roots/wordpress-core-installer": "^1.100",
"roots/wordpress-full": "^6.0",
"wp-coding-standards/wpcs": "^2.3",
"wp-phpunit/wp-phpunit": "^6.0",
"yoast/phpunit-polyfills": "^1.0"
},
"scripts": {
"lint": "phpcs",
Expand Down
Loading

0 comments on commit f3232d9

Please sign in to comment.