There’s a very popular question on Stack Overflow - how to specify a sender in a “MyCompany info@mycompany.com” format? Well, the answer is to specify it exactly like that, no brainer. However, the accepted answer (91 votes) suggests this: @recipients = “"#{user.name}" <#{user.email}>”. This is totally wrong. A better answer (150 votes) suggests this:
require ‘mail’
address = Mail::Address.new user.email
address.display_name = user.name
address.format
This is the right answer - but it doesn’t feel the Rails way of doing things. In ERB/Slim templates, we say <%= user.email %> or = user.email, and we know everything will be escaped and not interpreted as HTML. I think ActionMailer could also take care about e-mail escaping. Example:
I think this is an example of stackoverflow-driven development. Unless I misunderstand you, the answer you seek is already in the Rails guides Action Mailer Basics — Ruby on Rails Guides
I added this link to the stackoverflow question. Generally, any question from 2009 should be ignored.
2.3.4 Sending Email With Name
Sometimes you wish to show the name of the person instead of just their email address when they receive the email. The trick to doing that is to format the email address in the format "Full Name <email>".
IYou misunderstood me. I’m stating that the current Rails way of doing that is error prone and subject to encoding errors and even injection. My reference to StackOverflow is to show it’s something that a lot of developers face every day, the accepted answer is wrong, and - this is disturbing - the official guides seem to endorse the wrong way of doing that.
The code you pasted right from the docs is also wrong as it suggests to perform an unsafe operation no different to suggesting to use <%= user.name.html_safe %> and not <%= user.name %>). It’s just like one of the StackOverflow answers that I described as “wrong”. The only safe way is to use Mail::Address#format. Just imagine what happens if user.name contains a double-quote. Answer: no e-mail gets delivered as From field doesn’t follow the RFC. The worst-case scenario is when user.name is Nowak" blah@nowak.com, "original. This is like SQL injection, but e-mail From injection.
The trick to doing that is to format the email address in the format “Full Name ” but you should never put user input to full name or e-mail (e.g. try #{user.email}). Everything has to be correctly encoded with an appropriate encoder to prevent broken encoding or injection.
Talk is cheap. Here’s a demo of a successful injection:
class AdminMailer < ActionMailer::Base
default from: ‘test@nowaker.net’
def welcome_email(user)
@user = user
email_with_name = %(“#{@user.name}” <#{@user.email}>) # EXACT COPY-PASTE FROM DOCS
mail(to: email_with_name, subject: ‘Welcome to My Awesome Site’)
end
end
class TestUser
attr_accessor :email
attr_accessor :name
end
This approach is fragile because the interpolated value is not escaped, which could break the code or deliver to multiple recipients if exploited properly.
I'd like to suggest the Rails core team to provide a safer way to send e-mails to named recipients in a safer way.