This post will contain some generic information about whitelisting, but also some specific information that pertains to our service (Forefront Online). But the process would be similar for any email server.
Over the past couple of weeks, I have received a couple of inquiries about spam leaking through our filters. When I examine the messages, it’s because our customers have created rules to Allow messages from a certain sender to get through the filters. For the sake of discussion, let’s say it is UPS (ups.com) because UPS is a frequent victim of spoofing attacks.
Because UPS is such a large organization, a lot of our customer base communicates with them. This is perfectly normal and expected. However, our customer base also is worried about missing emails from UPS. It doesn’t matter if it is one-to-one communication (which is less likely to get filtered) or automated reports (which for some reason are always more likely to get filtered no matter which spam filter you use). To circumvent this, customers sometimes create Allow rules – if the mail comes from ups.com, allow it to pass through without being filtered.
The problem, as I discussed above, is that UPS is a frequent victim of spoofing. Spammers will say you have a package and include either a malware attachment or a link to a malware site. They then send zero-day spam before it arrives on any IP blocklist. The filter is about to execute but the customer rule says “Because it is from ups.com, skip filtering and deliver.” The result is that malicious mail gets to the end user’s inbox.
The correct way to allow mail from ups.com is not through a simple Allow rule that operates on the sending domain. Because mail can be spoofed, looking at the sender (either the P1 From address or the P2 From address) is not good enough. When people want to receive mail from ups.com, they want to receive mail that is actually from ups.com, not mail that claims to be from ups.com.
So how do we do this?
The correct way to do this is to create an Allow rule that combines the sender and the results of an authentication check. In our environment, the simplest way is with an SPF Pass. Since an SPF check authenticates the sending domain, and because ups.com is someone you want to hear from, the Allow rule must contain both of those components. Below is a screenshot of how you would do it in our User Interface:
Breaking it down:
- The rule is an Allow rule
- The sender domain is ups.com
- The x-header to look for is Received-SPF and the value is pass.
Doing it this way lets you receive mail from UPS while avoiding malicious content from spoofed senders (spam from a compromised UPS account will sail right through, however).
Some notes about this solution:
- You don’t have to do an SPF check. This would also work with DKIM validation. Our service does not do DKIM validation but others do. Most of the time it doesn’t matter because most domains that you want to hear from and safelist that sign with DKIM also publish SPF records.
- Some domains don’t sign with DKIM or publish SPF records. In this case, you need to create allow rules on the sending IP addresses and either combine it with the sender or drop the sender altogether.
- Our service strips pre-existing Received-SPF headers. If you do this on your own, if a spammer spoofs it, you must either strip it and restamp it, or use the one that your own service stamps if you don’t strip the pre-existing one (i.e, you could have multiple Received-SPF headers).
- If you create allow rules on sending IP addresses because the sender doesn’t publish SPF records, and the sending IP address is shared among several domains (more common for small organizations), then you run the risk of safelisting other domains that use the same IP.
- You can still create safe senders with no SPF checks or IP address checks, but you should only do it on a specific email address (i.e., email@example.com vs @ups.com). This makes it less likely for a spammer to guess what is on your safe senders list (a single address) vs sending from any random email address and getting through.
And that’s the proper way to implement a whitelist.