Soundboard clip blob URLs are never revoked and survive logout #57

Closed
opened 2026-09-12 01:51:18 -04:00 by jared · 0 comments
Owner

Severity: low · Type: security · Confidence: high

Location: src/app/utils/soundboardClips.ts:16-34, src/client/initMatrix.ts:110-134

Problem

objectUrlCache is a module-level Map<mxc, blobUrl> that is written on every clip play/preview and never revoked or cleared. Clips from encrypted rooms are decrypted media, so the decrypted bytes stay reachable via a live blob: URL for the whole page session, including across logoutClient() — which wipes IndexedDB, the search index and the clearPlaintextCaches localStorage set, but not this map (the reload afterwards is what actually drops it). The cache is also unbounded across packs (the 40-clip cap is per pack, not global), so a user browsing many space packs accumulates blobs at up to 1 MB each.

How to trigger

play clips from several packs, then inspect retained blob URLs; or log out and observe the map is untouched before the reload.

Suggested fix

add a clearSoundboardClipCache() that URL.revokeObjectURLs every entry, call it from logoutClient/clearCacheAndReload (alongside clearPlaintextCaches), and cap the map with LRU eviction that revokes on evict.


Filed from the September 2026 client audit (branch lotus @ 4bea4895).

**Severity:** low · **Type:** security · **Confidence:** high **Location:** `src/app/utils/soundboardClips.ts:16-34`, `src/client/initMatrix.ts:110-134` ### Problem `objectUrlCache` is a module-level `Map<mxc, blobUrl>` that is written on every clip play/preview and never revoked or cleared. Clips from encrypted rooms are decrypted media, so the decrypted bytes stay reachable via a live `blob:` URL for the whole page session, including across `logoutClient()` — which wipes IndexedDB, the search index and the `clearPlaintextCaches` localStorage set, but not this map (the reload afterwards is what actually drops it). The cache is also unbounded across packs (the 40-clip cap is per pack, not global), so a user browsing many space packs accumulates blobs at up to 1 MB each. ### How to trigger play clips from several packs, then inspect retained blob URLs; or log out and observe the map is untouched before the reload. ### Suggested fix add a `clearSoundboardClipCache()` that `URL.revokeObjectURL`s every entry, call it from `logoutClient`/`clearCacheAndReload` (alongside `clearPlaintextCaches`), and cap the map with LRU eviction that revokes on evict. --- _Filed from the September 2026 client audit (branch `lotus` @ 4bea4895)._
jared added this to the Audit 2026-09 · Medium & Low milestone 2026-09-12 01:51:18 -04:00
jared added the bugpriority: lowsecurityarea: calls labels 2026-09-12 01:51:18 -04:00
jared self-assigned this 2026-09-12 01:51:18 -04:00
jared closed this issue 2026-09-12 20:29:01 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#57