bitwarden / bitwarden/ios

[PM-40644] iOS Watch app crashes when encrypted Core Data data is invalid

Open
#2,895 2 comments 0 reactions 0 assignees View on GitHub
app:password-manager bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.