Skip to content

Commit

Permalink
Added check against HIBP API when setting a password.
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmorrison committed Dec 10, 2024
1 parent a6e63a7 commit 28190b8
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions includes/classes/Authentication/Passwords.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class Passwords {

use Singleton;

/**
* Stores the Have I Been Pwned API URL
*/
const API_URL = 'https://api.pwnedpasswords.com/range/';

/**
* Setup hooks
*
Expand Down Expand Up @@ -307,6 +312,11 @@ public function validate_strong_password( $errors, $user_data ) {
return $errors;
}

// Validate the password against the Have I Been Pwned API.
if ( ! $this->is_password_secure( $password ) && is_wp_error( $errors ) ) {
$errors->add( 'password_reset_error', __( '<strong>ERROR:</strong> The password entered may have been included in a data breach and is not considered safe to use. Please choose another.', 'tenup' ) );
}

// Should a strong password be enforced for this user?
if ( $user_id ) {

Expand Down Expand Up @@ -374,4 +384,44 @@ public function enforce_for_user( $user_id ) {

return $enforce;
}

/**
* Check if password is secure by querying the Have I Been Pwned API.
*
* @param string $password Password to validate.
*
* @return bool True if password is ok, false if it shows up in a breach.
*/
protected function is_password_secure( $password ): bool {
$hash = strtoupper( sha1( $password ) );
$prefix = substr( $hash, 0, 5 );
$suffix = substr( $hash, 5 );

$response = wp_remote_get( self::API_URL . $prefix );

// Allow for a failed request to the HIPB API.
if ( is_wp_error( $response ) ) {
return true;
}

$body = wp_remote_retrieve_body( $response );

// Allow for a failed request to the HIPB API.
if ( is_wp_error( $body ) ) {
return true;
}

$lines = explode( "\r\n", $body );

foreach ( $lines as $line ) {
$parts = explode( ':', $line );

// If the suffix is found in the response, the password may be in a breach.
if ( $parts[0] === $suffix ) {
return false;
}
}

return true;
}
}

0 comments on commit 28190b8

Please sign in to comment.