FIX: Parse address lists in embedded emails (#14514)

Same fix is applied to emails immediately after being parsed because
long headers are sometimes in an invalid format.
This commit is contained in:
Bianca Nenciu 2021-10-06 15:07:29 +03:00 committed by GitHub
parent 20e70d0ac5
commit f58ab2283d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 20 deletions

View File

@ -3,7 +3,6 @@
require "digest"
module Email
class Receiver
# If you add a new error, you need to
# * add it to Email::Processor#handle_failure()
@ -72,8 +71,7 @@ module Email
# do not create a new `IncomingEmail` record to avoid double ups.
return if @incoming_email = find_existing_and_update_imap
ensure_valid_address_lists
ensure_valid_date
Email::Validator.ensure_valid!(@mail)
@from_email, @from_display_name = parse_from_field
@from_user = User.find_by_email(@from_email)
@ -121,22 +119,6 @@ module Email
incoming_email
end
def ensure_valid_address_lists
[:to, :cc, :bcc].each do |field|
addresses = @mail[field]
if addresses&.errors.present?
@mail[field] = addresses.to_s.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i)
end
end
end
def ensure_valid_date
if @mail.date.nil?
raise InvalidPost, I18n.t("system_messages.email_reject_invalid_post_specified.date_invalid")
end
end
def is_blocked?
return false if SiteSetting.ignore_by_title.blank?
Regexp.new(SiteSetting.ignore_by_title, Regexp::IGNORECASE) =~ @mail.subject
@ -915,7 +897,13 @@ module Email
end
def embedded_email
@embedded_email ||= embedded_email_raw.present? ? Mail.new(embedded_email_raw) : nil
@embedded_email ||= if embedded_email_raw.present?
mail = Mail.new(embedded_email_raw)
Email::Validator.ensure_valid_address_lists!(mail)
mail
else
nil
end
end
def process_forwarded_email(destination, user)

28
lib/email/validator.rb Normal file
View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
module Email
class Validator
def self.ensure_valid!(mail)
Email::Validator.ensure_valid_address_lists!(mail)
Email::Validator.ensure_valid_date!(mail)
mail
end
def self.ensure_valid_address_lists!(mail)
[:to, :cc, :bcc].each do |field|
addresses = mail[field]
if addresses&.errors.present?
mail[field] = addresses.to_s.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i)
end
end
end
def self.ensure_valid_date!(mail)
if mail.date.nil?
raise Email::Receiver::InvalidPost, I18n.t("system_messages.email_reject_invalid_post_specified.date_invalid")
end
end
end
end

View File

@ -2024,4 +2024,12 @@ describe Email::Receiver do
expect { receive(email_3) }.to change { Topic.count }.by(0).and change { Post.where(post_type: Post.types[:regular]).count }.by(1)
end
end
it 'fixes valid addresses in embedded emails' do
Fabricate(:group, incoming_email: "group-fwd@example.com")
process(:long_embedded_email_headers)
incoming_email = IncomingEmail.find_by(message_id: "example1@mail.gmail.com")
expect(incoming_email.cc_addresses).to include("a@example.com")
expect(incoming_email.cc_addresses).to include("c@example.com")
end
end

View File

@ -0,0 +1,21 @@
MIME-Version: 1.0
Date: Sat, 2 Oct 2021 21:52:36 -0400
Message-ID: <example1@mail.gmail.com>
Subject: Fwd: Test Email
From: Example Group <group@example.com>
To: group-fwd@example.com
Cc: C <c@example.com>, D <d@
example.com>
---------- Forwarded message ---------
Date: Sat, 2 Oct 2021 21:52:36 -0400
Message-ID: <example2@mail.gmail.com>
Subject: Test Email
From: User <user@example.com>
To: Example Group <group@example.com>
Cc: A <a@example.com>, B <
b@example.com>
Hello world!