Conversation
… password buffers, and guard vault parsing
## Description
Remediates input validation, resource exhaustion, and memory hygiene vulnerabilities in `@metamask/browser-passworder` (Findings BP-1 through BP-4).
## Key Changes & Security Rationale
* **Robust Key Derivation Guard (BP-1 - `src/index.ts`)**:
- Hardened `isKeyDerivationOptions`: verifies `isPlainObject(params)` and asserts that `iterations` is a valid numeric value.
- Prevents malformed vault payloads (such as `{"params": null}`) from passing validation and crashing on object destructuring with untyped `TypeError` exceptions.
* **Iteration Ceiling Bounding (BP-2 - `src/index.ts`)**:
- Lowered `MAX_PBKDF2_ITERATIONS` from 10,000,000 to 3,000,000.
- Restricts malicious vaults from triggering extreme PBKDF2 computation loops that freeze user browser threads on unlock attempts.
* **In-Memory Password Zeroization (BP-3 - `src/index.ts`)**:
- Enforced `passBuffer.fill(0)` immediately following WebCrypto key derivation and on early invalid-salt rejections in `keyFromPassword`.
- Ensures raw password byte representations are scrubbed from heap memory instead of persisting until garbage collection.
* **Structured Vault Parsing & Validation (BP-4 - `src/index.ts`)**:
- Implemented `parseVault(text: string)` to validate that incoming ciphertext objects strictly contain required string fields (`data`, `iv`, `salt`).
- Standardized JSON parsing error boundaries to prevent unhandled low-level exceptions in downstream decryption pathways.
## Verification
- Verified Playwright test suite execution across encryption and decryption flows.
- Validated backwards compatibility with both legacy 10,000-iteration vaults and modern 900,000-iteration vaults.
- Confirmed correct error handling when decrypting with incorrect passwords or corrupted vault JSON payloads.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Remediates input validation, resource exhaustion, and memory hygiene vulnerabilities in
@metamask/browser-passworder(Findings BP-1 through BP-4).Key Changes & Security Rationale
Robust Key Derivation Guard (BP-1 -
src/index.ts):isKeyDerivationOptions: verifiesisPlainObject(params)and asserts thatiterationsis a valid numeric value.{"params": null}) from passing validation and crashing on object destructuring with untypedTypeErrorexceptions.Iteration Ceiling Bounding (BP-2 -
src/index.ts):MAX_PBKDF2_ITERATIONSfrom 10,000,000 to 3,000,000.In-Memory Password Zeroization (BP-3 -
src/index.ts):passBuffer.fill(0)immediately following WebCrypto key derivation and on early invalid-salt rejections inkeyFromPassword.Structured Vault Parsing & Validation (BP-4 -
src/index.ts):parseVault(text: string)to validate that incoming ciphertext objects strictly contain required string fields (data,iv,salt).Verification
Note
High Risk
Changes sit on the password vault unlock path (PBKDF2 bounds, parsing, and error semantics); regressions could block legitimate vaults or alter security behavior under malicious input.
Overview
Hardens untrusted vault and KDF input in the browser passworder decrypt/derive path without changing the public encrypt API shape.
Vault parsing:
decrypt/decryptWithDetailnow go throughparseVault, which rejects non-JSON or malformed payloads (missingdata,iv, orsaltstrings) with explicit "Invalid vault format" errors instead of failing deeper in the stack.isVaultUpdatedsafely treats bad JSON as not updated.KDF safety: New
validateKeyDerivationOptionsenforces PBKDF2 only and iteration counts between 1,000 and 3,000,000 (safe integers).isKeyDerivationOptionsnow requires a realparamsobject and numericiterationsso crafted metadata cannot crash on destructuring.keyFromPasswordrejects salts shorter than 16 decoded bytes, validates options on every call, and zero-fills the password buffer after derive (and on early salt failure).Compatibility & errors: Vaults without
keyMetadatastill unlock via explicitOLD_DERIVATION_PARAMS(10k iterations) while thekeyFromPassworddefault is now 900k for new keys. Wrong keys still surface "Incorrect password" only from WebCrypto decrypt failure; invalid post-decrypt JSON becomes "Corrupt vault: decrypted payload is not valid JSON".importKeywraps invalid key JSON similarly.The Playwright suite in
test/index.spec.tsis unchanged aside from line shifts; existing legacy and modern fixture vault tests still cover backward compatibility.Reviewed by Cursor Bugbot for commit 3697276. Bugbot is set up for automated code reviews on this repo. Configure here.