42 lines
2 KiB
Diff
42 lines
2 KiB
Diff
# UNDF: UNDF-2026-000000855
|
|
# UNDF: (leave blank)
|
|
# CWE-407: NotificationService mentioned users Array#include? in select loop
|
|
# Severity: MEDIUM
|
|
# Speedup: ~100x at R=100 recipients, M=100 mentioned users
|
|
# File: app/services/notification_service.rb
|
|
# Two methods filter notification recipients against a list of mentioned
|
|
# users using Array#include? inside .select:
|
|
# 1. new_mentions_in_resource_email (line 844)
|
|
# 2. send_new_mentions_in_note_notifications (line 911)
|
|
# new_mentioned_users is an Array, so each include? is O(M). Called for
|
|
# each of R recipients, total O(R * M). On issues/MRs with many
|
|
# participants and @-mentions, both R and M can grow large.
|
|
# Fix: convert new_mentioned_users to a Set before the select loop.
|
|
--- a/app/services/notification_service.rb
|
|
+++ b/app/services/notification_service.rb
|
|
@@ -841,7 +841,8 @@ class NotificationService
|
|
end
|
|
|
|
def new_mentions_in_resource_email(target, new_mentioned_users, current_user, method)
|
|
unless current_user&.can_trigger_notifications?
|
|
warn_skipping_notifications(current_user, target)
|
|
return false
|
|
end
|
|
|
|
recipients = NotificationRecipients::BuildService.build_recipients(target, current_user, action: "new")
|
|
- recipients = recipients.select { |r| new_mentioned_users.include?(r.user) }
|
|
+ mentioned_set = new_mentioned_users.to_set
|
|
+ recipients = recipients.select { |r| mentioned_set.include?(r.user) }
|
|
|
|
recipients.each do |recipient|
|
|
mailer.send(method, recipient.user.id, target.id, current_user.id, recipient.reason).deliver_later
|
|
@@ -909,7 +910,8 @@ class NotificationService
|
|
|
|
def send_new_mentions_in_note_notifications(note, new_mentioned_users)
|
|
recipients = NotificationRecipients::BuildService.build_new_note_recipients(note)
|
|
- recipients = recipients.select { |r| new_mentioned_users.include?(r.user) }
|
|
+ mentioned_set = new_mentioned_users.to_set
|
|
+ recipients = recipients.select { |r| mentioned_set.include?(r.user) }
|
|
|
|
send_note_notifications(note, recipients)
|
|
end
|