In my previous blog post How to use Safe Senders in EOP and FOPE, I explained that in the EOP and FOPE service, the spam filter inspects the 5321.MailFrom when doing a safe senders check whereas Outlook adds the 5322.From address (the one you see in your email client) to the safe senders list.
The question is: Why does EOP and FOPE use the 5321.MailFrom and not the 5322.From?
The reason is: Security. By respecting the 5322.From address, spammers could abuse the safe sender functionality to deliver messages to the inbox without filtering.
In EOP and FOPE, the spam filter does not respect a safe sender if the sender hard fails an SPF check. This is to prevent a user from adding a sender as a safe sender, a spammer spoofing it and then the message getting a free pass to the inbox. For example, suppose that I added firstname.lastname@example.org to my safe senders list.
Example 1 - Spam filter inspects 5321.MailFrom, Spammer spoofs my safe sender in the 5321.MailFrom and 5322.From
RFC 5321.MailFrom = email@example.com [This will hard fail an SPF check!]RFC 5322.From = firstname.lastname@example.org
Because this message hard fails an SPF check, it will undergo spam filtering where it will be flagged as spam and delivered to my junk folder even though I said "I want to receive all messages from Paypal." The spam filter respects your wishes except when it has probable cause not to. If the spam filter inspected the 5322.From address and it matched the safe sender and skipped filtering, the user would have an unfiltered malicious message in his or her inbox. While some spam messages do get past the filter, we want to minimize this where possible.
Example 2 - Spam filter inspects 5321.MailFrom, Spammer spoofs my safe sender only in the 5322.From
RFC 5321.MailFrom = email@example.com [This message is SPF None since blah-blah-blah.com does not exist]RFC 5322.From = firstname.lastname@example.org
This message will undergo spam filtering because the 5321.From is not on the user's safe sender list. If the spam filter inspected the 5322.From address and it matched the safe sender and skipped filtering, the user would have an unfiltered malicious message in his or her inbox.
Example 3 - Spam filter inspects 5321.MailFrom, Spammer spoofs my safe sender only in the 5322.From but it passes an SPF
RFC 5321.MailFrom = email@example.com [This message passes and SPF check since the spammer registered the domain and set up SPF records]RFC 5322.From = firstname.lastname@example.org
From Example 1 and 2, you may be tempted to say "Why not respect the 5322.From address if it passes an SPF check?" The reason is that there is not a relationship between the 5321.MailFrom and the 5322.From address. In this example, the message passed an SPF check and the From: address the user sees is on his safe sender list. However, it is not actually coming from the safe sender and instead is an SPF workaround the spammer has implemented. Once again, we want this message to undergo spam filtering.If the spam filter inspected the 5322.From address and it matched the safe sender and skipped filtering, the user would have an unfiltered malicious message in his or her inbox.
Example 4 - Spam filter inspects 5321.MailFrom, sender legitimately sends email from my safe sender in the 5321.MailFrom
RFC 5321.MailFrom = email@example.com [This message passes an SPF check because it legitimately arrives from the sender]RFC 5322.From = firstname.lastname@example.org
In this example, the message actually comes from Paypal. The SPF check passes and therefore is delivered to the user's inbox. This doesn't mean that a message must pass an SPF check in order to respect a safe sender, only that it must not fail.
That's the rationale for respecting the 5321.MailFrom address. Respecting the 5322.From address makes it too easy to exploit. But on the other hand, most of the senders you want to skip filtering for will have the same 5321.MailFrom as 5322.From address so adding it to your safe senders from Outlook is a de facto 5321.MailFrom addition. It is a balance between security (avoiding maliciously spoofed email going to the end user because they safe sendered them; we have seen this many times) and having the email client do what the user expects it will do (clicking "Do not block" resulting in one-click addition to safe lists because users do not know the difference between 5321.MailFrom's and 5322.From's).
Where this doesn't work is when the two From: addresses are different which is frequently the case in Bulk Email. When this occurs, users must manually add them to the Safe Senders list.
Note: in Example 3, there is a relationship between the 5322.From address and the DKIM-signed d= field if DMARC is being enforced. But that's out-of-scope of this blog post.
Technically there is a relationship between the 5321.MailFrom and 5322.From address if DMARC is enforced, but the identifiers must be either identical (strict DMARC) or sub-domains (relaxed DMARC). The way safe senders works in our service is a bit like strict DMARC alignment.
Quick reality check, a "hard fail" in SPF should be rejected, but the paypal.com SPF record shown by `nslookup -q=txt paypal.com` ends with ~all, i.e., soft fail, not hard fail. Nothing new here, PayPal always published an "anonymous coward" soft fail SPF record ;-)
You are correct, I should have either called out that Paypal publishes an SPF and this example is *if* they published hard fail but they actually publish Soft Fail.