[PM-40644] iOS Watch app crashes when encrypted Core Data data is invalid
- Dominant language
- Swift
- Stars
- 684
- Forks
- 154
- Avg merge
- 7d 2h
- Merged PRs (30d)
- 32
Description
### Steps To Reproduce
1. On a paired Apple Watch, have the Bitwarden Watch app store a cipher with an encrypted string attribute.
2. Make that persisted encrypted value malformed or unreadable (for example, restore or corrupt the Watch app’s local store so it no longer matches the keychain key).
3. Launch the Watch app or open the view that reads the affected cipher.
### Expected Result
The Watch app should treat unreadable encrypted data as unavailable, log the failure, and stay running.
### Actual Result
CryptoService.decrypt force-unwraps the AES-GCM decoding and decryption operations with try!. Any malformed, tampered, or wrong-key ciphertext throws and terminates the Watch process before StringEncryptionTransformer can return nil.
### Screenshots or Videos
Not applicable (source-level crash path; no device capture in this audit).
### Additional Context
Static analysis of iOS source snapshot commit 7ecd504. The affected path is BitwardenWatchApp/Entities/StringEncryptionTransformer.swift, which calls CryptoService.decrypt when Core Data transforms encrypted values. Both decrypt overloads used try! for AES.GCM.SealedBox(combined:) and AES.GCM.open.
Prepared fix: local commit ac95bfe on branch fix/watch-corrupt-encrypted-data-crash converts those operations to do/catch, logs the failure, and returns nil. This is an availability/robustness bug; no confidentiality or integrity bypass was demonstrated.
Validation:
- git diff --check passed.
- Source check confirms no try! or plainData! remains in CryptoService.
- watchOS runtime tests are pending because this is a Windows host without Xcode/watchOS tooling.
### Build Version
2026.4.0 source snapshot (commit 7ecd504; not device-tested)
### What server are you connecting to?
US
### Self-host Server Version
_No response_
### Environment Details
- Target: Bitwarden Watch app (watchOS)
- Reproduction environment: source audit; no physical device used
- Validation host: Windows 11 (no Xcode/watchOS runtime)
### Issue Tracking Info
- [x] I understand that work is tracked outside of Github. A PR will be linked to this issue should one be opened to address it, but Bitwarden doesn't use fields like "assigned", "milestone", or "project" to track progress.
Contributor guide
Research direction
Start in BitwardenWatchApp/Entities/StringEncryptionTransformer.swift and follow its calls to the two CryptoService.decrypt overloads. Verify the malformed or wrong-key Core Data value is treated as unavailable, the failure is logged, and the Watch process remains running; runtime validation requires Xcode/watchOS tooling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- mobile-dev, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100