mirror of
https://github.com/zulip/zulip.git
synced 2025-11-11 17:36:27 +00:00
CVE-2023-32678: Prevent unauthorized editing/deletion in priv streams.
Users who used to be subscribed to a private stream and have been removed from it since retain the ability to edit messages/topics, and delete messages that they used to have access to, if other relevant organization permissions allow these actions. For example, a user may be able to edit or delete their old messages they posted in such a private stream. An administrator will be able to delete old messages (that they had access to) from the private stream. We fix this by fixing the logic in has_message_access (which lies at the core of our message access checks - access_message() and bulk_access_messages()) to not rely on only a UserMessage row for checking access but also verify stream type and subscription status.
This commit is contained in:
committed by
Alex Vandiver
parent
51e3ed0262
commit
c908b518ef
@@ -852,13 +852,9 @@ def has_message_access(
|
||||
* The optional stream parameter is validated; is_subscribed is not.
|
||||
"""
|
||||
|
||||
# If you have a user_message object, you have access.
|
||||
if has_user_message:
|
||||
return True
|
||||
|
||||
if message.recipient.type != Recipient.STREAM:
|
||||
# You can't access direct messages you didn't receive
|
||||
return False
|
||||
# You can only access direct messages you received
|
||||
return has_user_message
|
||||
|
||||
if stream is None:
|
||||
stream = Stream.objects.get(id=message.recipient.type_id)
|
||||
@@ -869,21 +865,26 @@ def has_message_access(
|
||||
# You can't access public stream messages in other realms
|
||||
return False
|
||||
|
||||
if not stream.is_history_public_to_subscribers():
|
||||
# You can't access messages you didn't directly receive
|
||||
# unless history is public to subscribers.
|
||||
return False
|
||||
def is_subscribed_helper() -> bool:
|
||||
if is_subscribed is not None:
|
||||
return is_subscribed
|
||||
|
||||
return Subscription.objects.filter(
|
||||
user_profile=user_profile, active=True, recipient=message.recipient
|
||||
).exists()
|
||||
|
||||
if stream.is_public() and user_profile.can_access_public_streams():
|
||||
return True
|
||||
|
||||
# is_history_public_to_subscribers, so check if you're subscribed
|
||||
if is_subscribed is not None:
|
||||
return is_subscribed
|
||||
if not stream.is_history_public_to_subscribers():
|
||||
# Unless history is public to subscribers, you need to both:
|
||||
# (1) Have directly received the message.
|
||||
# AND
|
||||
# (2) Be subscribed to the stream.
|
||||
return has_user_message and is_subscribed_helper()
|
||||
|
||||
return Subscription.objects.filter(
|
||||
user_profile=user_profile, active=True, recipient=message.recipient
|
||||
).exists()
|
||||
# is_history_public_to_subscribers, so check if you're subscribed
|
||||
return is_subscribed_helper()
|
||||
|
||||
|
||||
def bulk_access_messages(
|
||||
|
||||
Reference in New Issue
Block a user