Scope the remaining room-visibility queries to the viewer's enclaves (LC-606) #562
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/lc606-scope-remaining-room-queries"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes LC-606.
LC-604 fixed the two unread queries that leaked message bodies. This finishes the class: four more consumers carried the same drifted predicate (
room_type = 'public' OR room_members, no enclave condition), and the audit this ticket asked for found two dashboard card queries with no visibility filter at all. All now useaccessible_rooms_sql, the shared fragment mirroringis_room_accessible.What was leaking
list_roomsfed the forward-message picker (forward.rs:42) and the rooms API (api.rs:98), so both offered channels from enclaves the caller is not in and would be refused on open. Not a write vector - the forward POST already re-validates the destination. The separate admin query is gone: the admin arm of the fragment reduces to the sameroom_type != 'dm'it ran.The activity feed (three queries) could surface an item from a room the viewer cannot open: someone in another enclave
@-mentions you, or you keep receiving replies and reactions for messages you posted before being removed from an enclave.feed_for_usernow takesis_admin, threaded from the route.count_unread_mentions_per_roomhad no room filter whatsoever - it counted mentions in any room, so a mention written in an enclave the viewer is not in produced a count and, on the dashboard's Mentions card, revealed that the room exists.followed_threads_with_unreadselected the room name and the parent message body with no visibility filter, so a viewer removed from an enclave kept receiving both for threads they still follow.room_ids_with_draftswas audited and deliberately left alone: it reads the viewer's own drafts and returns no room content.That closes the "unverified either way" item I left on LC-604 - two of those three cards were in fact leaking, which is why I would not call them clean on the strength of an empty card.
Tests
Five leak tests in
inbox_enclave_scoping.rs, each verified to fail against the old predicate and pass with the new one (I reverted the predicate in place, keeping arity, to prove it):Two fixtures had to be corrected, and this is the interesting part
db_mentionsanddb_private_roomscreated rooms withenclave_id = None- which no production channel has (migration 0009 backfills every non-DM room) and whichis_room_accessibletreats as unreachable for a non-admin.Left alone, they would have gone green for the wrong reason:
delete_mentions_returns_unread_userswould have passed because everything was filtered out, not because the rows were deleted;test_list_rooms_excludes_private_for_non_memberwould have held trivially, since nothing was visible to anyone.Both now use enclave-backed fixtures, and the private-room test puts the viewer in the enclave but not the room, so it tests room membership rather than holding vacuously.
test_list_rooms_includes_private_for_memberis what caught this - it failed loudly, which is what prompted checking its siblings.Verified live
generalandrandom, which she cannot open).just checkclean, full suite green, and thelc77fixtures stay clean after a local run now that LC-605 has landed.🤖 Generated with Claude Code
https://claude.ai/code/session_01P2Lh6DKB15inZTb5z8miu7