-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[PM-28813] Implement encryption diagnostics & recovery tool #17673
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
Conversation
|
Great job! No new security vulnerabilities introduced in this pull request |
d4a17c2 to
248289a
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #17673 +/- ##
==========================================
+ Coverage 41.70% 41.74% +0.04%
==========================================
Files 3571 3580 +9
Lines 103769 104208 +439
Branches 15613 15670 +57
==========================================
+ Hits 43281 43506 +225
- Misses 58653 58863 +210
- Partials 1835 1839 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Claude finished @quexten's task —— View job Code Review Completed
Overall Assessment: REQUEST CHANGESThis PR implements a valuable encryption diagnostics and recovery tool with good architecture, but has critical security and error handling issues that must be addressed before merge. Critical Issues:
Critical Findings1. PII Logging Violation ❌File: logger.record(`User ID: ${userId}`);Issue: This violates the project rule "NEVER log decrypted data, encryption keys, or PII". User IDs are PII. Fix: logger.record("User information retrieved successfully");2. Unsafe Non-Null Assertion ❌File: await this.privateKeyRegenerationService.regenerateUserPublicKeyEncryptionKeyPair(
workingData.userId!, // Non-null assertion without verification
);Issue: The code uses Fix: async runRecovery(workingData: RecoveryWorkingData, logger: LogRecorder): Promise<void> {
if (!workingData.userId) {
logger.record("Cannot recover: missing user ID");
throw new Error("User ID required for private key recovery");
}
// ... existing dialog code ...
logger.record("Replacing private key");
await this.privateKeyRegenerationService.regenerateUserPublicKeyEncryptionKeyPair(
workingData.userId // No assertion needed
);
logger.record("Private key replaced successfully");
}3. Missing Error Context in Diagnostics
|
apps/web/src/app/key-management/data-recovery/data-recovery.component.ts
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/steps/user-info-step.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.ts
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.html
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.ts
Outdated
Show resolved
Hide resolved
Thomas-Avery
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet tool and great work. Would like to see more test coverage for example on the steps. A few things to look at from my side.
apps/web/src/app/key-management/data-recovery/data-recovery.component.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.html
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/data-recovery.component.spec.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/steps/sync-step.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/steps/folder-step.ts
Outdated
Show resolved
Hide resolved
apps/web/src/app/key-management/data-recovery/steps/cipher-step.ts
Outdated
Show resolved
Hide resolved
...rc/user-asymmetric-key-regeneration/abstractions/user-asymmetric-key-regeneration.service.ts
Show resolved
Hide resolved
|
@Thomas-Avery apologies for the force push, I had a wrong |
c332d85 to
8b91222
Compare
8b91222 to
ec3da97
Compare
Thomas-Avery
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looked over the force push. Just the items left unresolved and one missing async action.

🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-28813
bitwarden/server#6659
📔 Objective
To get diagnostics for certain types of encryption related issues, and to fix users vaults, this PR adds a tool that:
Repairing the vault here means replacing the private keys, should they be corrupt, and removing vault items / folders, should they be corrupt.
This will help CS track down issues and resolve issues with customers faster.
📸 Screenshots
Note: In the video the private key stays corrupt. This is because the code used when recording the video marks all private keys as corrupt, just for testing / demo purposes.
Screen.Recording.2025-12-01.at.12.21.28.mov
⏰ Reminders before review
🦮 Reviewer guidelines
:+1:) or similar for great changes:memo:) or ℹ️ (:information_source:) for notes or general info:question:) for questions:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion:art:) for suggestions / improvements:x:) or:warning:) for more significant problems or concerns needing attention:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt:pick:) for minor or nitpick changes