Menü schliessen
Created: July 24th 2018
Last updated: April 21st 2022
Categories: Common Web Development,  Linux
Author: Marcus Fleuti

[SOLVED] SPF setting does not apply to Return-Path causing more spam and phishing e-mails | Spamassassin | Postfix

Donation Section: Background
Monero Badge: QR-Code
Monero Badge: Logo Icon Donate with Monero Badge: Logo Text
82uymVXLkvVbB4c4JpTd1tYm1yj1cKPKR2wqmw3XF8YXKTmY7JrTriP4pVwp2EJYBnCFdXhLq4zfFA6ic7VAWCFX5wfQbCC

What is SPF and how does it work?

SPF = Sender Policy Framework. It's a mechanism which is designed to protect your domain (example.com) from being misused by somebody else. If you are the owner of example.com you can add an information to the DNS of your domain that's claiming which mailservers are allowed to send e-mail on your behalf. Such an entry looks like this:

example.com.  TXT  "v=spf1 ip4:185.175.165.155 -all"

The entry defines, that only the server with the IP-Adress 185.175.165.155 is allowed to send e-mails that end with @example.com.

But who checks the SPF setting - who is protecting you?

Every receiving e-mail server has to do check, whether the e-mail it's about to receive is coming from a domain that has SPF enabled in its DNS or not. If SPF is enabled the receiving mail server checks if the sender is allowed to send e-mails in the name of @example.com or not.
The "-all" parameter means: If the sending e-mail server is not in the SPF list the receiving mail server will reject the e-mail immediately. This should be the default in a properly configured productive environment.
This protects the owner of @example.com from hackers who try to send e-mails on behalf of @example.com.

Why is SPF important?

SPF is very important because without it, a hacker can pretend to be like ceo@example.com.
Real life examples:

  1. A hacker could send an e-mail to chiefoffinance@example.com in the name of the CEO of that company. In that e-mail he would tell the Chief of Finance to send a certain amount of money to a dedicated bank account. If the CFO is a bit sloppy or for whatever reason this could have a negative impact on business.
  2. A market competitor could hire someone who starts sending out false statements to the media in the name of @example.com

What's the problem with SPF checking?

There's a big problem with SPF checking. SPF checks the so called FROM header information. This e-mail header information looks like this:

From: Example Company <info@example.com>
  1. The receiving mail sever analyzes the FROM header entry
  2. The domain example.com is identified
  3. The recipient checks example.com's DNS server for an SPF entry
  4. It checks the SPF values if the e-mail sending mail server is listed
  5. If it's listed => OK , if it's not listed => reject e-mail

That's pretty straight forward and works in like 99% of the cases without any problem.

What is Return-Path and what is it for?

There's a second e-mail header entry called Return-Path. The Return-Path defines, from where the e-mail has actually come from (from which server). The Return-Path is used in this scenario:

  1. A newsletter e-mail is sent in the name of newsletter@example.com through another e-mail server
  2. The other/external e-mail server (newsletter mail server) is sending the e-mail on behalf of newsletter@example.com (instead of the company's real mail server). This server must be allowed to do so in the SPF syntax resulting in this server being able to send e-mails but not to receive e-mails for example.com.
  3. The sending e-mail server MUST know, when an e-mail is undeliverable and adds the Return-Path header, so that the receiving e-mail server can return bounce information to the newsletter provider in case an e-mail cannot be sent. This is very important for statistical reasons but also to optimize the newsletter providers' e-mail systems.
  4. Since the e-mail is sent with newsletter@example.com sender address (this is set in the FROM header in this case), answers like automatically generated vacation messages, out of office messages or even answers from recipients will be correctly deliverd to the company's e-mail server via the address newsletter@example.com.

Why exactly is there a problem between Return-Path and SPF?

The big problem is that SPF looks at the FROM header as long as there's no Return-Path set. As soon as the sending e-mail server sets the Return-Path, the receiving server has to ignore SPF checking on the FROM. In most regular cases the FROM header contains the same information as the Return-Path. In that case SPF works as it should. But this can be exploited.

Example on how the SPF security can be exploited

  1. A hacker configures his own e-mail server which sets a Return-Path header to whatever value he likes. Let's call that Return-Path: Hackerman <hackerman@hackedserver.com>
  2. The hacker uses this e-mail server to send an e-mail to chiefoffinance@example.com with the sender name (FROM) ceo@example.com and the Return-Path Hackerman <hackerman@hackedserver.com>
  3. The Return-Path is obviously silly. If one looks at the header he'd instantly notice, that this e-mail is NOT coming from the CEO. But the problem is that no e-mail client is showing this information anywhere clearly. The only place this information can be found is in the detailed header information which no regular user knows where to find. And no regular user ever bothers with this.
  4. The SPF checking logic sees that the e-mail is coming from chiefoffinance@example.com but ignores any SPF check because a proper Return-Path has been set.
  5. The e-mail will be accepted by the recieving e-mail server and delivered to the recipient.

Why do Postfix nor Spamassassin check the SPF when Return-Path value is set?

On first look it looks like a security breach. But actually it's not. The real-life problem is that some other server, which is not example.com, must be able to send out e-mails in the name of your company. That's why SPF has been defined this way. If another server delivers the e-mail the SPF system is looking for a proper SPF value for that sending e-mail server. If a hacker has set up his own e-mail server he can put whatever he likes and make this work. Or in other words: SPF only works if hackers use botnetworks to send out spam but it fails if a real hacker is abusing the system by misusing properly configured e-mail servers for sending out phishing e-mails. That a big flaw of the system which SPF cannot solve. It has to be solved with other technical implementations (namely DNSSEC and DMARC).

What can be done to prevent a hacker from abusing my domain like that?

We've searched quite a while to find a proper and easy way. We came up with an idea:
In like 95+ percent of all e-mails received the sender is a regular e-mail sender using Microsoft Outlook or any other e-mail client to send out e-mails. In all these cases the FROM and Return-Path values contain the same domain information. So what we want to do is the following:

  1. Create a Spamassassin rule that checks, if the 2 header values, From and Return-Path, are using the same domain.
  2. If they do NOT contain the same domain information there's a higher spam probability and we'll add more spam-points to the e-mail

How to properly configure Spamassassin and Postfix?

Spamassassin is the way to go. The reason is because we do not want to directly reject an e-mail but to allow it to softly go through the spamfilter which can add additional points to it if we think the e-mail might be coming from an abuser. For this we created a Spamassassin Regex rule:
The Spamassassin rule needs to be added to the Spamassassin configuration file which is usually located here:

/etc/spamassassin/local.cf

Add the following 2 entries to that file:

header RETURNPATH_FROM_MISMATCH ALL =~ /(?:^.*[\s\S])*^Return-Path:.*?@(?:[a-z0-9?=_%+-]*\.)*([a-z0-9?=_%+-]+\.[a-z0-9?=_%+-]+)\>[\s\S]+^From:.*@(?!(?:[a-z0-9?=_%+-]*\.)*\1\>).*\R[\s\S]+/ims
describe RETURNPATH_FROM_MISMATCH Return-Path / From mismatch.
score RETURNPATH_FROM_MISMATCH 4.0

 

header FROM_RETURNPATH_MISMATCH ALL =~ /(?:^.*[\s\S])*^From:.*@(?:[a-z0-9?=_%+-]*\.)*([a-z0-9?=_%+-]+\.[a-z0-9?=_%+-]+)\>[\s\S]+^Return-Path:.*@(?!(?:[a-z0-9?=_%+-]*\.)*\1\>).*\R[\s\S]+/ims
describe FROM_RETURNPATH_MISMATCH From / Return-Path mismatch.
score FROM_RETURNPATH_MISMATCH 4.0

Exit and save the file. Check with the following syntax if everything is working well. If the command below does not return any error and exists without giving any message you're good to go:

spamassassin --lint

What does Spamassassin do with this code do and why to enter 2 filters?

  1. The regex code is applied to all header information of the e-mail. It checks if the domain in the Return-Path field is the same as the domain mentioned in the From field.
  2. If the 2 domains are not the same => 7 points are added to this e-mail. Usually e-mails with more than 5 points are considered spam. In this case the e-mail will be most probably put into the spam folder.
  3. The second rule does basically the same. The problem is that some mailservers put the FROM header value above the Return-Path value. This difference in the field ordering need to be addressed with 2 different Spamassassin rules.

Pros and Cons in using this Spamassassin configuration

Pros

  1. Dubious e-mails will be filtered out as spam. A hacker can no longer misuse the Return-Path to undermine SPF checking
  2. E-Mails don't get lost. Recipients can fetch wrongly filtered out e-mails from the spam folder and they can be whitelisted
  3. This solution solves the SPF flaw easily and reliably but has some downsides too...

Cons

  1. Most newsletters will be filtered out as spam. While many people consider this as a blessing, some people want to receive such newsletters => Reliable newsletter sources must be manually whitelisted

Further Spamassassin optimizations / Ideas

We are having the following ideas in mind. If you have a solution to it you're highly welcomed to comment on this issue - thank you!

  1. Instead of assigning point values e-mails could just be flagged as "potentially dangerous" in the e-mail subject (Spamassassin e-mail subject rewrite)
  2. A whitelist spamfolder could be defined into which a user could move an e-mail into and a script will fetch those e-mails and automatically add them to the whitelist