Problem
crates/crypto/src/lib.rs:483-599 implements RatchetCache, which stores derived ChannelKey values in a BTreeMap. While ChannelKey derives ZeroizeOnDrop, the cache has no method to explicitly wipe all keys when a user leaves a channel or server.
pub struct RatchetCache {
ratchets: BTreeMap<u32, KeyRatchet>,
cache: BTreeMap<(u32, u64), ChannelKey>,
max_entries: usize,
}
Old keys accumulate in memory until eviction pressure (cache full → oldest entry removed) or the cache is dropped. In a long-lived session with active channels, hundreds of old message keys may reside in WASM linear memory.
Severity
MEDIUM — information disclosure risk. A process with memory access (core dump, malicious browser extension reading WASM memory, Spectre-class side channels) could extract previously-derived keys, allowing decryption of old messages.
Fix
Add an explicit clear() method and call it on channel leave:
impl RatchetCache {
/// Wipe all cached keys and ratchets. Call on channel leave / server exit.
pub fn clear(&mut self) {
self.cache.clear();
self.ratchets.clear();
}
}
The existing evict_epoch() method (line 585) provides per-epoch cleanup but must be called explicitly. Wire it into the client's channel-leave / server-disconnect flow.
Locations
crates/crypto/src/lib.rs:483-599 — RatchetCache struct
crates/crypto/src/lib.rs:585 — evict_epoch (exists but not called on leave)
Problem
crates/crypto/src/lib.rs:483-599implementsRatchetCache, which stores derivedChannelKeyvalues in aBTreeMap. WhileChannelKeyderivesZeroizeOnDrop, the cache has no method to explicitly wipe all keys when a user leaves a channel or server.Old keys accumulate in memory until eviction pressure (cache full → oldest entry removed) or the cache is dropped. In a long-lived session with active channels, hundreds of old message keys may reside in WASM linear memory.
Severity
MEDIUM — information disclosure risk. A process with memory access (core dump, malicious browser extension reading WASM memory, Spectre-class side channels) could extract previously-derived keys, allowing decryption of old messages.
Fix
Add an explicit
clear()method and call it on channel leave:The existing
evict_epoch()method (line 585) provides per-epoch cleanup but must be called explicitly. Wire it into the client's channel-leave / server-disconnect flow.Locations
crates/crypto/src/lib.rs:483-599— RatchetCache structcrates/crypto/src/lib.rs:585— evict_epoch (exists but not called on leave)