mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 05:23:35 +00:00
CVE-2022-31168: Fix authorization check for changing bot roles.
Due to an incorrect authorization check in Zulip Server 5.4 and earlier, a member of an organization could craft an API call that grants organization administrator privileges to one of their bots. Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
committed by
Matt Keller
parent
93d2c77225
commit
c9f6830ba6
@@ -8,9 +8,10 @@ from django.core import mail
|
||||
from django.test import override_settings
|
||||
from zulip_bots.custom_exceptions import ConfigValidationError
|
||||
|
||||
from zerver.actions.bots import do_change_bot_owner
|
||||
from zerver.actions.realm_settings import do_set_realm_property
|
||||
from zerver.actions.streams import do_change_stream_permission
|
||||
from zerver.actions.users import do_change_can_create_users, do_deactivate_user
|
||||
from zerver.actions.users import do_change_can_create_users, do_change_user_role, do_deactivate_user
|
||||
from zerver.lib.bot_config import ConfigError, get_bot_config
|
||||
from zerver.lib.bot_lib import get_bot_handler
|
||||
from zerver.lib.integrations import EMBEDDED_BOTS, WebhookIntegration
|
||||
@@ -1169,6 +1170,42 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
||||
bot = self.get_bot()
|
||||
self.assertEqual(None, bot["default_sending_stream"])
|
||||
|
||||
def test_patch_bot_role(self) -> None:
|
||||
self.login("desdemona")
|
||||
|
||||
email = "default-bot@zulip.com"
|
||||
user_profile = self.get_bot_user(email)
|
||||
|
||||
do_change_user_role(user_profile, UserProfile.ROLE_MEMBER, acting_user=user_profile)
|
||||
|
||||
req = dict(role=UserProfile.ROLE_GUEST)
|
||||
|
||||
result = self.client_patch(f"/json/users/{self.get_bot_user(email).id}", req)
|
||||
self.assert_json_success(result)
|
||||
|
||||
user_profile = self.get_bot_user(email)
|
||||
self.assertEqual(user_profile.role, UserProfile.ROLE_GUEST)
|
||||
|
||||
# Test for not allowing a non-owner user to make assign a bot an owner role
|
||||
desdemona = self.example_user("desdemona")
|
||||
do_change_user_role(desdemona, UserProfile.ROLE_REALM_ADMINISTRATOR, acting_user=None)
|
||||
|
||||
req = dict(role=UserProfile.ROLE_REALM_OWNER)
|
||||
|
||||
result = self.client_patch(f"/json/users/{user_profile.id}", req)
|
||||
self.assert_json_error(result, "Must be an organization owner")
|
||||
|
||||
# Test for not allowing a non-administrator user to assign a bot an administrator role
|
||||
shiva = self.example_user("shiva")
|
||||
self.assertEqual(shiva.role, UserProfile.ROLE_MODERATOR)
|
||||
self.login_user(shiva)
|
||||
do_change_bot_owner(user_profile, shiva, acting_user=None)
|
||||
|
||||
req = dict(role=UserProfile.ROLE_REALM_ADMINISTRATOR)
|
||||
|
||||
result = self.client_patch(f"/json/users/{user_profile.id}", req)
|
||||
self.assert_json_error(result, "Must be an organization administrator")
|
||||
|
||||
def test_patch_bot_to_stream_private_allowed(self) -> None:
|
||||
self.login("hamlet")
|
||||
user_profile = self.example_user("hamlet")
|
||||
|
||||
@@ -39,6 +39,7 @@ from zerver.lib.exceptions import (
|
||||
CannotDeactivateLastUserError,
|
||||
JsonableError,
|
||||
MissingAuthenticationError,
|
||||
OrganizationAdministratorRequired,
|
||||
OrganizationOwnerRequired,
|
||||
)
|
||||
from zerver.lib.integrations import EMBEDDED_BOTS
|
||||
@@ -188,11 +189,11 @@ def update_user_backend(
|
||||
|
||||
if role is not None and target.role != role:
|
||||
# Require that the current user has permissions to
|
||||
# grant/remove the role in question. access_user_by_id has
|
||||
# already verified we're an administrator; here we enforce
|
||||
# that only owners can toggle the is_realm_owner flag.
|
||||
# grant/remove the role in question.
|
||||
if UserProfile.ROLE_REALM_OWNER in [role, target.role] and not user_profile.is_realm_owner:
|
||||
raise OrganizationOwnerRequired()
|
||||
elif not user_profile.is_realm_admin:
|
||||
raise OrganizationAdministratorRequired()
|
||||
|
||||
if target.role == UserProfile.ROLE_REALM_OWNER and check_last_owner(user_profile):
|
||||
raise JsonableError(
|
||||
|
||||
Reference in New Issue
Block a user