Skip to content

[SEC-W-08] localStorage keys not namespaced per identity; sign-out / identity-switch does not purge #245

@intendednull

Description

@intendednull

Commit: 2f26d91 · Finding: SEC-W-08

Problem

All persisted app state — identity, message DB (willow_msgs_<hash>), trust store, recents, theme — shares a single global localStorage namespace with no identity prefix:

  • crates/client/src/storage.rs:312-381,428-440MessageDb::msg_key hashes only the topic, not (identity_pub || topic).
  • crates/web/src/trust_store.rs:20-150 — trust flags under global keys.
  • crates/web/src/palette_recents.rs:22-70 — recents under a single key.
  • crates/web/src/components/downgrade_banner.rs:28-60 — per-peer banner dismissals under global key.

When a user signs in as a different identity (or a second user uses the same browser), they inherit the previous identity's decrypted messages, trust flags, and recents. There is also no Client::sign_out() that purges.

Fix

  • Key every persisted item by <hash(identity_pubkey)>:<logical-key>.
  • Add Client::sign_out() that iterates localStorage for the current identity prefix, removes matching keys, calls caches.delete, unregisters the SW, and reloads.
  • Optional Phase-2: wrap message-DB blobs with AES-GCM using a key derived from the identity seed so disk-level access can't read them.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions