Skip to content

Commit

Permalink
CVE-2024-21630: Check permission to subscribe others using invite link.
Browse files Browse the repository at this point in the history
This commit updates the API to check the permission to subscribe other
users while creating multi-use invites. The API will raise error if
the user passes the "stream_ids" parameter (even when it contains only
default streams) and the calling user does not have permission to
subscribe others to streams.

We did not add this before as we only allowed admins to create
multiuse invites, but now we have added a setting which can be used
to allow users with other roles as well to create multiuse invites.
  • Loading branch information
sahil839 authored and timabbott committed Jan 25, 2024
1 parent bfcde65 commit 0df7bd7
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
59 changes: 59 additions & 0 deletions zerver/tests/test_invite.py
Expand Up @@ -2463,6 +2463,65 @@ def test_create_multiuse_link_with_specified_streams_api_call(self) -> None:
self.assert_length(get_default_streams_for_realm_as_dicts(self.realm.id), 1)
self.check_user_subscribed_only_to_streams("alice", [])

def test_multiuse_invite_without_permission_to_subscribe_others(self) -> None:
realm = get_realm("zulip")
members_group = UserGroup.objects.get(
name=SystemGroups.MEMBERS, realm=realm, is_system_group=True
)
do_change_realm_permission_group_setting(
realm, "create_multiuse_invite_group", members_group, acting_user=None
)
do_set_realm_property(
realm, "invite_to_stream_policy", Realm.POLICY_ADMINS_ONLY, acting_user=None
)

self.login("hamlet")
stream_names = ["Rome", "Scotland", "Venice"]
streams = [get_stream(stream_name, self.realm) for stream_name in stream_names]
stream_ids = [stream.id for stream in streams]
result = self.client_post(
"/json/invites/multiuse",
{
"stream_ids": orjson.dumps(stream_ids).decode(),
"invite_expires_in_minutes": 2 * 24 * 60,
},
)
self.assert_json_error(
result, "You do not have permission to subscribe other users to streams."
)

result = self.client_post(
"/json/invites/multiuse",
{
"stream_ids": orjson.dumps([]).decode(),
"invite_expires_in_minutes": 2 * 24 * 60,
},
)
self.assert_json_success(result)

self.login("iago")
result = self.client_post(
"/json/invites/multiuse",
{
"stream_ids": orjson.dumps(stream_ids).decode(),
"invite_expires_in_minutes": 2 * 24 * 60,
},
)
self.assert_json_success(result)

do_set_realm_property(
realm, "invite_to_stream_policy", Realm.POLICY_MEMBERS_ONLY, acting_user=None
)
self.login("hamlet")
result = self.client_post(
"/json/invites/multiuse",
{
"stream_ids": orjson.dumps(stream_ids).decode(),
"invite_expires_in_minutes": 2 * 24 * 60,
},
)
self.assert_json_success(result)

def test_create_multiuse_invite_group_setting(self) -> None:
realm = get_realm("zulip")
full_members_system_group = UserGroup.objects.get(
Expand Down
3 changes: 3 additions & 0 deletions zerver/views/invite.py
Expand Up @@ -227,6 +227,9 @@ def generate_multiuse_invite_backend(
)
streams.append(stream)

if len(streams) and not user_profile.can_subscribe_other_users():
raise JsonableError(_("You do not have permission to subscribe other users to streams."))

invite_link = do_create_multiuse_invite_link(
user_profile, invite_as, invite_expires_in_minutes, streams
)
Expand Down

0 comments on commit 0df7bd7

Please sign in to comment.