SECURITY: Filter unread bookmark reminders the user cannot see

There is an edge case where the following occurs:

1. The user sets a bookmark reminder on a post/topic
2. The post/topic is changed to a PM before or after the reminder
   fires, and the notification remains unread by the user
3. The user opens their bookmark reminder notification list
   and they can still see the notification even though they cannot
   access the topic anymore

There is a very low chance for information leaking here, since
the only thing that could be exposed is the topic title if it
changes to something sensitive.

This commit filters the bookmark unread notifications by using
the bookmarkable can_see? methods and also prevents sending
reminder notifications for bookmarks the user can no longer see.
This commit is contained in:
Martin Brennan
2023-10-13 11:41:10 +10:00
committed by Krzysztof Kotlarek
parent 6183d9633d
commit 3c5fb871c0
13 changed files with 114 additions and 21 deletions

View File

@ -55,7 +55,8 @@ class NotificationsController < ApplicationController
end
end
notifications = filter_inaccessible_notifications(notifications)
notifications =
Notification.filter_inaccessible_topic_notifications(current_user.guardian, notifications)
json = {
notifications: serialize_data(notifications, NotificationSerializer),
@ -82,7 +83,8 @@ class NotificationsController < ApplicationController
total_rows = notifications.dup.count
notifications = notifications.offset(offset).limit(60)
notifications = filter_inaccessible_notifications(notifications)
notifications =
Notification.filter_inaccessible_topic_notifications(current_user.guardian, notifications)
render_json_dump(
notifications: serialize_data(notifications, NotificationSerializer),
total_rows_notifications: total_rows,
@ -155,10 +157,4 @@ class NotificationsController < ApplicationController
def render_notification
render_json_dump(NotificationSerializer.new(@notification, scope: guardian, root: false))
end
def filter_inaccessible_notifications(notifications)
topic_ids = notifications.map { |n| n.topic_id }.compact.uniq
accessible_topic_ids = guardian.can_see_topic_ids(topic_ids: topic_ids)
notifications.select { |n| n.topic_id.blank? || accessible_topic_ids.include?(n.topic_id) }
end
end