I've had this noted down on some of my code for a while:
/**
* Add a BCC.
*
* Note that according to the conventions of the SMTP protocol all
* addresses, including BCC addresses, are included in every email as it
* is sent over the Internet. The BCC addresses are stripped off blind
* copy email only at the destination email server.
*
* @param string $email
* @param string $name
* @return object Email
*/
I don't remember where I got it from (possible source) but that shouldn't be relevant to this question. Basically, whenever I try to send an email with BCCs via SMTP the BCC addresses are not hidden - I've read the whole RFC for the SMTP protocol (a couple years ago) and I don't think I'm missing anything.
The strange thing is, if I send an email with BCCs using the built-in mail()
function everything works just right and I've no idea why - I would like to roll my own email sender but I fail to understand this.
Can someone please shed some light into this dark subject?
The BCC addresses are not stripped off at the destination email server. That's not how it works.
How SMTP actually works
RCPT TO
commands to the SMTP server, one for each receiver email addresses, and this command does not distinguish whether the receiver is a normal To, CC or BCC type receiver.DATA
command, in which will contain the content of the email - which consist of the email headers and body - the one that are received by email clients. Among these email headers are the usual from address, to address, CC address.DATA
command, not because the destination SMTP server stripped them away. The destination SMTP server will just refer to theRCPT TO
for the list of email addresses that should receive the email content. It does not really care whether the receiver is in the To, CC or BCC list.Update (to clarify): BCC email addresses must be listed in the
RCPT TO
command list, but the BCC header should not be printed under theDATA
command.Quoting a part of the RFC that I think is relevant to your case:
Rolling out your own email sender
A couple of years ago, I frankly think, is quite a long time back to assume that you still memorize end-to-end of RFC 821. :)
Very late, but the accepted answer is essentially wrong.
First off, SMTP has nothing to do with
BCC
. SMTP, as a protocol, is concerned only with a return path (theMAIL
request), a list of recipients (theRCPT
request), and the data to be transferred (theDATA
request). If you want to send an email to somebody via SMTP, then you have to supply their address in aRCPT
request, period.The contents of an email - the
DATA
, effectively - are specified completely separately, in RFC2822. There's a lot of latitude in howBCC
should be handled. The spec gives 3 ways of handlingBCC
, and in only one of them is theBCC
stripped out while preparing the email. If I use Thunderbird as an email client, for example, and point it to an SMTP server, and then look at the message on the line, then I find that the ThunderbirdBCC
has gone (from the SMTPDATA
), and the SMTP connection instead contains a standardRCPT
request for thebcc
'ed address. So, Thunderbird convertsBCC
toRCPT
, but that's not the only way to do it.Another place to handle
BCC
is at the MTA - in other words, whatever SMTP server your mail client is pointed to. Sendmail, for example, searches all of theTo
,Cc
, andBcc
lines in the SMTPDATA
, and then constructs an address list from those lines, and then removes theBcc
line. You can persuade Sendmail to keep theBcc
if you want to. If sendmail isn't the destination MTA, then it will connect to another MTA over SMTP, and send the recipient addresses viaRCPT
. In other words, if sendmail is the destination MTA, and it gets aBcc
, it will strip it out, contrary to Amry's statement.There's also some confusion in the comments. You can specify
RCPT
addresses to any domain, not just a list of addresses in the same domain. The MTA has to look up the MX records for the destination domains to work out where to send everything. The google.com and yahoo.com statements are wrong.