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

fix: clear encryption salt and key #4514

Merged
merged 3 commits into from
Jul 12, 2024
Merged

fix: clear encryption salt and key #4514

merged 3 commits into from
Jul 12, 2024

Conversation

owencraston
Copy link
Contributor

@owencraston owencraston commented Jul 10, 2024

Explanation

  • Currently, when a user locks the app and then resets their password, they are not able to log in wth their new password.
  • This is because the encryption key was generated with the old password and not cleared.
  • The solve this we will remove the encryption key from state when the user locks the wallet as well as when #createNewVaultWithKeyring is called.
  • This allows for a new encryption key to be generated with the new password when the user logs in again and submitPassword is called.

References

Changelog

@metamask/keyring-controller

  • FIXED: Reset encryption key when wallet is locked or when new vault is created to ensure that encryption key is always based on most recent password.

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

@owencraston owencraston changed the title fix: fix: new password is not recognized; Metamask only accepts the old password after wallet reset Jul 10, 2024
@owencraston owencraston marked this pull request as ready for review July 10, 2024 20:42
@owencraston owencraston requested a review from a team as a code owner July 10, 2024 20:42
Copy link
Contributor

@MajorLift MajorLift left a comment

Choose a reason for hiding this comment

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

How would you feel about replacing all of the toBeUndefined checks with not.toHaveProperty?

Checking for property would be the stricter test here, as the current checks would pass if the properties exist and are set to undefined at runtime.

// `controller.state`
{ ..., encryptionKey: undefined, encryptionSalt: undefined }

packages/keyring-controller/src/KeyringController.test.ts Outdated Show resolved Hide resolved
packages/keyring-controller/src/KeyringController.test.ts Outdated Show resolved Hide resolved
packages/keyring-controller/src/KeyringController.test.ts Outdated Show resolved Hide resolved
@owencraston owencraston requested a review from Gudahtt July 10, 2024 22:19
@gantunesr gantunesr changed the title fix: new password is not recognized; Metamask only accepts the old password after wallet reset fix: clear encryption salt and key Jul 10, 2024
@owencraston
Copy link
Contributor Author

@MajorLift good suggestion. I have made those changes in the latest commit.

@mikesposito
Copy link
Member

This makes sense when the intention is to create a new vault with createNewVaultAndKeychain. But wouldn't the user be best served using the changePassword method? The purpose of this method is exactly changing only the password, as opposed to recreating the entire vault manually.

On the other hand, caching the encryption key allows us to make decryption faster as we skip derivation (the most time-consuming step), so clearing it out on lock would lose its purpose

@owencraston
Copy link
Contributor Author

@mikesposito this is correct but in speaking with @Gudahtt he did not feel comfortable using that method in the extension yet. Perhaps this is the best long term solution though 🤔

@Gudahtt
Copy link
Member

Gudahtt commented Jul 12, 2024

But wouldn't the user be best served using the changePassword method? The purpose of this method is exactly changing only the password, as opposed to recreating the entire vault manually.

changePassword is for when the wallet is unlocked. In the "forgot password" flow, the wallet is locked so we cannot use that method.

Gudahtt
Gudahtt previously approved these changes Jul 12, 2024
Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

LGTM! Just two nits about adding newlines

@owencraston owencraston merged commit 6aaa484 into main Jul 12, 2024
116 checks passed
@owencraston owencraston deleted the fix/password-reset branch July 12, 2024 21:27
owencraston added a commit to MetaMask/metamask-extension that referenced this pull request Jul 15, 2024
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
1. What is the reason for the change?
- This fix addresses a user facing bug in production
- When a user locks the wallet and goes through the forget password
flow, the wallet is not accessible with the new password. Instead the
user must use the old password to unlock the wallet.
- This is a bug in the keyring controller because the encryptionKey gets
generated with the old password and is not reset when the user locks the
wallet and generates a new password.
2. What is the improvement/solution?
- This fix patches the keyring controller such that when the user locks
the wallet the encryption key gets cleared
- We also clear the encryption key in the`#createNewVaultWithKeyring` to
ensure a new encryption key is generated with the new password when the
user logs in again and submitPassword is called.
- This patch will be removed once [this
PR](MetaMask/core#4514) ships in the keyring
controller library

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/25787?quickstart=1)

## **Related issues**

Fixes: #25696

## **Manual testing steps**

- Open the extension
- Proceed to Forget password flow
- Paste your secret recovery phrase
- Set a new different password
- Proceed to Restore your Wallet
- After entering the account, lock it and try to login with the new
password
- It will throw an Invalid password error

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**


https://github.com/MetaMask/metamask-extension/assets/22918444/a63ef8fc-5ddf-40c7-b097-d2af29265765

### **After**


https://github.com/MetaMask/metamask-extension/assets/22918444/a963397e-dd69-41c7-9012-566ccdfce7c2


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
MajorLift pushed a commit that referenced this pull request Jul 16, 2024
## Explanation
- Currently, when a user locks the app and then resets their password,
they are not able to log in wth their new password.
- This is because the encryption key was generated with the old password
and not cleared.
- The solve this we will remove the encryption key from state when the
user locks the wallet as well as when `#createNewVaultWithKeyring` is
called.
- This allows for a new encryption key to be generated with the new
password when the user logs in again and `submitPassword` is called.

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

* Fixes MetaMask/metamask-extension#25696
* Moves path from [this
PR](MetaMask/metamask-extension#25753) into the
KeyringController

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/keyring-controller`

- **FIXED**: Reset encryption key when wallet is locked or when new
vault is created to ensure that encryption key is always based on most
recent password.

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
owencraston added a commit to MetaMask/metamask-extension that referenced this pull request Jul 18, 2024
## **Description**

1. What is the reason for the change?
- This fix addresses a user facing bug in production
- When a user locks the wallet and goes through the forget password
flow, the wallet is not accessible with the new password. Instead the
user must use the old password to unlock the wallet.
- This is a bug in the keyring controller because the encryptionKey gets
generated with the old password and is not reset when the user locks the
wallet and generates a new password.
2. What is the improvement/solution?
- This fix upgrades the keyring controller to version
[17.1.1](https://github.com/MetaMask/core/blob/main/packages/keyring-controller/CHANGELOG.md#1711)
which fixes this bug by clearing the encryption key/salt when the user
locks the wallet as well as when they submit their password. This
ensures that the encryption key is always in sync with the latest
password.
- The keyring controller pr for this fix can be found
[here](MetaMask/core#4514)
- This change involved a major version bump for the keyring controller
from 16 to 17.
[Here](https://github.com/MetaMask/core/blob/main/packages/keyring-controller/CHANGELOG.md#1711)
is the changelog for this bump.


[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/25847?quickstart=1)

## **Related issues**

Fixes: #25696

## **Manual testing steps**
- Open the extension
- Proceed to Forget password flow
- Paste your secret recovery phrase
- Set a new different password
- Proceed to Restore your Wallet
- After entering the account, lock it and try to login with the new
password
- You should be able to log in with your new password

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**


https://github.com/MetaMask/metamask-extension/assets/82837486/0de00905-ee01-4241-a90e-da60c5eb0976

### **After**


https://github.com/user-attachments/assets/f1f091c4-8974-415d-af28-d7b0b46184cb


## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
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.

[Bug]: The new password is not recognized; Metamask only accepts the old password after wallet reset
4 participants