CVE-2024-27286: Run usermessage modifications even for change_one.

This `if new_stream is not None` block was improperly indented,
causing it to only run if the propagation mode was not `change_one`.
Since the block controlled creation and deletion of UserMessage rows,
this led to messages being improperly still visible to members of the
old stream if they were being moved from public to private streams.
Clients also failed to receive `delete_message` events, so the
messages remained visible in their feeds until they reloaded the
application.
This commit is contained in:
Alex Vandiver 2024-03-06 22:02:48 +00:00 committed by Alex Vandiver
parent c3488bfe76
commit e964536139
2 changed files with 79 additions and 61 deletions

View File

@ -731,9 +731,7 @@ def do_update_message(
Attachment.objects.filter(messages__in=changed_messages.values("id")).update(
is_realm_public=None,
)
ArchivedAttachment.objects.filter(
messages__in=changed_messages.values("id")
).update(
ArchivedAttachment.objects.filter(messages__in=changed_messages.values("id")).update(
is_realm_public=None,
)
@ -741,9 +739,7 @@ def do_update_message(
Attachment.objects.filter(messages__in=changed_messages.values("id")).update(
is_web_public=None,
)
ArchivedAttachment.objects.filter(
messages__in=changed_messages.values("id")
).update(
ArchivedAttachment.objects.filter(messages__in=changed_messages.values("id")).update(
is_web_public=None,
)

View File

@ -1460,6 +1460,7 @@ class MessageMoveStreamTest(ZulipTestCase):
history_public_to_subscribers: bool,
user_messages_created: bool,
to_invite_only: bool = True,
propagate_mode: str = "change_all",
) -> None:
admin_user = self.example_user("iago")
user_losing_access = self.example_user("cordelia")
@ -1484,6 +1485,9 @@ class MessageMoveStreamTest(ZulipTestCase):
)
self.send_stream_message(admin_user, old_stream.name, topic_name="test", content="Second")
self.assert_length(get_topic_messages(admin_user, old_stream, "test"), 2)
self.assert_length(get_topic_messages(admin_user, new_stream, "test"), 0)
self.assertEqual(
UserMessage.objects.filter(
user_profile_id=user_losing_access.id,
@ -1503,16 +1507,18 @@ class MessageMoveStreamTest(ZulipTestCase):
f"/json/messages/{msg_id}",
{
"stream_id": new_stream.id,
"propagate_mode": "change_all",
"propagate_mode": propagate_mode,
},
)
self.assert_json_success(result)
messages = get_topic_messages(admin_user, old_stream, "test")
self.assert_length(messages, 0)
messages = get_topic_messages(admin_user, new_stream, "test")
self.assert_length(messages, 3)
# We gain one more message than we moved because of a notification-bot message.
if propagate_mode == "change_one":
self.assert_length(get_topic_messages(admin_user, old_stream, "test"), 1)
self.assert_length(get_topic_messages(admin_user, new_stream, "test"), 2)
else:
self.assert_length(get_topic_messages(admin_user, old_stream, "test"), 0)
self.assert_length(get_topic_messages(admin_user, new_stream, "test"), 3)
self.assertEqual(
UserMessage.objects.filter(
@ -1545,6 +1551,22 @@ class MessageMoveStreamTest(ZulipTestCase):
user_messages_created=False,
)
def test_move_one_message_from_public_to_private_stream_not_shared_history(self) -> None:
self.parameterized_test_move_message_involving_private_stream(
from_invite_only=False,
history_public_to_subscribers=False,
user_messages_created=True,
propagate_mode="change_one",
)
def test_move_one_message_from_public_to_private_stream_shared_history(self) -> None:
self.parameterized_test_move_message_involving_private_stream(
from_invite_only=False,
history_public_to_subscribers=True,
user_messages_created=False,
propagate_mode="change_one",
)
def test_move_message_from_private_to_private_stream_not_shared_history(self) -> None:
self.parameterized_test_move_message_involving_private_stream(
from_invite_only=True,