I'm working on a problem that I'm seeing with an email scanning server (MailScanner, Spamassassin, Postfix, etc.), and From header spoofing. Unfortunately, some of the versions of these components are old, so this may be a bug in one or more of them. Upgrades are planned, I'm just seeing if an interim solution is appropriate, or if this is a configuration/rule issue that would need to carry over to the upgraded environment.

Basically, I'm seeing messages that contain multiple addresses in the From header coming through. That in itself seems to be RFC compliant, with specific conditions that usually aren't being met as far as I can see, however nearly every example that I can find that our environment has logged, this is a spoofed/malicious message.

Here are a few examples, all from different messages, with names changed to protect the (possibly) innocent:

From: "confirm@amazon.com" <confirm@amazon.com> <bad@hacker.man>
From: John Doe <jdoe@internet.com> <spoof@ing.mail>
From: "Trusted Third Party Employee" <trusted.employee@thirdparty.org> <spammer@foo.vn>

Email clients like Outlook seem to only display the first address. MailScanner/SpamAssassin use the last.

Basically, a regex like the following would seem to catch these (whether that is in a header_check in Postfix or a rule in Spamassassin):

^From: .*?<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}>.*<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}>

I'm sure that this regex is terrible and there are probably more elegant ways to match the examples like the ones above. ;)

I can share specific configuration snippets if relevant.

Any thoughts?

  • Exim4 seems to reject these type of From lines out of hand, F=<> rejected after DATA: syntax error in 'From:' header when scanning for sender: malformed address: <victim@contoso.com> may not follow Mr Spammer <naughty@spoof.com> in "Mr Spammer <naughty@spoof.com> <victim@contoso.com>" – roaima Jan 23 '19 at 23:15
  • Hmm, that makes me think that this is more of a bug with the version of Postfix involved. For now I'm testing this header rule in SA (had to simplify the regex to get it to pick anything up): From =~ /<\S+>.*<\S+>/i . – rickyboone Jan 23 '19 at 23:25

Currently I'm fighting this kind of spam, and to complement the great answer of Deeepdigger currently I have this rule in my Spamassassin.

describe LOCAL_TWO_FROM_EMAILS  The From has two emails, probably email spoofing
header   LOCAL_TWO_FROM_EMAILS  From =~ /<.*\@.*>\s+<.*\@.*>/i
score    LOCAL_TWO_FROM_EMAILS  9.0 # Set this value at your discretion

The regex part needs to be improved, but this rule has helped me to stop the majority of email been spoofed by this malformed header.

| improve this answer | |

As far as I can tell, all of these From headers are in violation of the RFC. There can be multiple addresses in a From header, but then they must be comma-separated.


So the mail server should be rejecting that email (imho). If it does not, you could add a header check to validate the RFC format and reject the email otherwise. But this regex would be complex and ugly, because the RFC allows for pretty much everything in the display-name.

E.g. this would be legal

    From: "confirm@amazon.com <confirm@amazon.com>" <bad@hacker.man>

In practice I have never in my life received a valid email with multiple From addresses. Also I consider everything in the display-name to be garbage, because it's totally at the discretion of the sender. Known email adresses are in my address book anyway (so they display in my Email client), and for all others I can discard the display-name to prevent phishing.

In other words if SpamAssassin uses the last valid email address in the header line as the REAL one, you can do the same and remove everything else:

/^From:.*[[:space:]]+<?([a-zA-Z0-9._?=#$|'*%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63})>?[[:space:]]*$/ REPLACE From: ${1}

Note: the pattern to match valid email adress formats is formally not correct but pragmatic. See also https://www.regular-expressions.info/email.html for a discussion on email adress format regexes.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.