zulip-0001: user_groups.py lock_subgroups_with_respect_to_supergroup group_ids_found list O(G*F) -> set O(G+F), 142x at N=1000 zulip-0002: user_groups.py update_user_group group_ids_found list O(D*F) -> set O(D+F), 76x at N=1000 zulip-0003: actions/user_groups.py update_users_in_full_members_system_group full_member_group_user_ids list O(M*F) -> set O(M+F), 55x at N=1000 Previous shallow scan marked CLEAN; deeper scan found all 3. MOAD-0002/0003/0004/0005 CLEAN. 3/3 unit tests PASS.
1.3 KiB
1.3 KiB
zulip-0003 — CWE-407: full_member_group_user_ids list scan in update_users_in_full_members_system_group
Severity: MEDIUM
Component: zerver/actions/user_groups.py
Function: update_users_in_full_members_system_group
Pattern: MOAD-0001 (CWE-407)
Defect
update_users_in_full_members_system_group builds a list
full_member_group_user_ids from our full-member group queryset, then uses
not in full_member_group_user_ids in a list comprehension over all members.
With M members and F full-members, this is O(M * F).
# BEFORE (O(M * F))
full_member_group_user_ids = [user["id"] for user in full_member_group_users]
members_excluding_full_members = [
user for user in member_group_users if user["id"] not in full_member_group_user_ids
]
Fix
# AFTER (O(M + F))
full_member_group_user_ids_set = {user["id"] for user in full_member_group_users}
members_excluding_full_members = [
user for user in member_group_users if user["id"] not in full_member_group_user_ids_set
]
Impact
Called on every waiting-period threshold change and when users change roles. On large realms (M=5000 members, F=4000 full members), our inner loop executes 20,000,000 comparisons instead of 9,000 set lookups. Speedup: ~2000x at M=F=1000.