mail icon indicating copy to clipboard operation
mail copied to clipboard

Sanitizing invalid characters from to field

Open jkhulme opened this issue 5 years ago • 1 comments

We're using v2.7.1 of the mail gem with ruby 2.4.4

Some of our users are typoing their names - not their email addresses - in ways that are causing syntax errors when we try and send the email.

Here are some examples, one that works fine, and two different failing examples - names have been changed, but the typos have been kept the same

Working:

to = "\"Joe Bloggs\" <[email protected]>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "Joe Bloggs" <[email protected]>>>

Failure 1:

to = "\"Joe B\"log-gs\" <[email protected]>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "Joe B"log-gs" <[email protected]>>>

Falure 2:

to = "\"JOE BLOGGS\\\" <[email protected]>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "JOE BLOGGS\" <[email protected]>>>

When we try and send the failures we get the error:

Net::SMTPSyntaxError: 501 Syntax error in parameters
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:969 in check_response
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:937 in getok
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:837 in mailfrom
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:658 in send_message
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp_connection.rb:54 in deliver!
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:101 in block in deliver!
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:519 in start
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:109 in start_smtp_session
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:100 in deliver!
/gems/mail-2.7.1/lib/mail/message.rb:276 in deliver!

I've tried to find out what the allowed characters in the to are, but I haven't been able to find it.

I'm wondering if there is something we could do escape the characters, I tried CGI.escape but it didn't seem to have the effect I wanted

"%22JOE+BLOGGS%5C%22+%3Cjoe.bloggs%40example.com%3E"
#<Mail::Message:92412660, Multipart: false, Headers: <To: %22JOE+BLOGGS%5C%22+%3Cjoe.bloggs%40example.com%3E>>

Any advice on how we could prevent the errors, and allow the emails to be sent correctly would be appreciated

jkhulme avatar Nov 01 '19 14:11 jkhulme

The rules here are quite complicated. You can read them in RFC5322 if you're interested.

But to summarize, in quoted names like you're using, you can use ASCII %d33-126, except for %d34 and %d92 (double quote and backslash). This is why your examples are having problems.

It is possible to escape those characters with a backslash. Maybe something like this would work for you?

email = "[email protected]"
name = "Joe B\"log-gs"
escaped_name = name.gsub(/\\/) { '\\\\' }.gsub(/"/) { '\"' }
to = "\"#{escaped_name}\" <#{email}>"

# Test this can be parsed:
Mail::AddressList.new(to)

barrettkingram avatar Feb 29 '20 19:02 barrettkingram