Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check haveibeenpwned API during password reset and account creation #170

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

jamesmorrison
Copy link
Member

Description of the Change

Verify new password against the Have I Been Pwned API during password change (on profile or via reset process)

Closes #77

How to test the Change

Changing password through profile

  1. Login to WP and access you profile
  2. Scroll down to "Set New Password" and enter something in a breach (e.g. london123)
  3. Scroll down to the "Update Profile" button
  4. If need be, remove the disabled attribute on the Update Profile button - this is added through JS when a "weak" password is identified
  5. Save and confirm you see the error: "The password entered may have been included in a data breach and is not considered safe to use. Please choose another." - note you may also see another error stating "Password must be medium strength or greater." (ignore this, but be aware of correlation between weak passwords and data breaches, in many cases both errors will show

Reset password process

  1. Navigate to WP login and run through the password reset process
  2. Open the link in the email
  3. In the new password field enter something in a breach (e.g. london123)
  4. If need be, remove the disabled attribute on the Save Password button - this is added through JS when a "weak" password is identified
  5. Save and confirm you see the error: "The password entered may have been included in a data breach and is not considered safe to use. Please choose another." - note you may also see another error stating "Password must be medium strength or greater." (ignore this, but be aware of correlation between weak passwords and data breaches, in many cases both errors will show

Changelog Entry

Added - Verify new password against the Have I Been Pwned API during password change (on profile or via reset process)

Credits

Props @jamesmorrison

Checklist:

$prefix = substr( $hash, 0, 5 );
$suffix = substr( $hash, 5 );

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: As per https://haveibeenpwned.com/API/v3#UserAgent, we need to specify the User Agent. The docs state:

The user agent should accurately describe the nature of the API consumer such that it can be clearly identified in the request. Not doing so may result in the request being blocked.

I think specifying 10up Experience WordPress Plugin should be sufficient, thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, should we cache this request/response to stop us spamming the API if someone resubmits the same pass multiple times?

*
* @return bool True if password is ok, false if it shows up in a breach.
*/
protected function is_password_secure( $password ): bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought (non-blocking): What are your thoughts on allowing engineers to opt-out of this functionality via a const or a filter?

@@ -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' ) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought (non-blocking): Do we want to trigger an error here, or should we add a warning to the screen pre-update? Alternatively, should there be a checkbox, like the weak password box, that lets them bypass this if they really want to use that password?

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Let's use a more descriptive name for this const. We might want to introduce additional APIs in the future.

Comment on lines +403 to +405
if ( is_wp_error( $response ) ) {
return true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (non-blocking): Remond me, does wp_remote_get() always return a WP_Error for non-200 responses? If not, should we also check wp_remote_retrieve_response_code()?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Check haveibeenpwned API during password reset and account creation
2 participants