A Proposal for Storing Envelope-Sender Data in Received Headers

Traditionally, the envelope-sender data has been added to messages as they pass through MTAs, but in varying ways (the Return-Path header, X-Envelope-From, etc.), and generally in terms of one header in the message. see EnvelopeSenderInHeaders.

A very helpful addition to support MUAs and MUA-level filters, would be if this was added to the Received header for the MTA handover, e.g.

  Received: from portent.example.com (portent.example.com [])
        by bar.example.org (envelope-from
        (Postfix) with ESMTP id 12CE931024F for <foo@example.org>;
        Wed, 28 Jan 2004 08:54:19 +0000 (GMT)

This would allow filters like SpamAssassin to pick up the envelope-from used at each step of the chain, which is very valuable especially when intermediate steps tend to rewrite it. (For example, fetchmail makes some incorrect assumptions, and will add an *incorrect* Return-Path header if an X-Envelope-From header exists, even from an earlier handover.)

If I recall correctly, some versions of exim seem to support this.

We already have support for this in SpamAssassin -- we detect it using this regexp matched against Received lines:

        /envelope-(?:sender|from)[ =](\S+)\b/

MTA authors/packagers, please consider adding this to your default configurations; inserting a string in the form

        (envelope-sender <foo@example.com>)

somewhere after the "from ... by ..." text would do the trick nicely.

MTAs That Do This

If you know of an MTA package that will add the envelope-sender data to the Received header, or can write a configuration stanza to add to config files to do this in any given MTA, please add a note about it on this page using the "EditText" button below.

received_header_text = Received: \
      ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\
      {${if def:sender_ident {from $sender_ident }}\
      ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}} }}\
      by $primary_hostname \
      ${if def:sender_address {(envelope-from\n\t\
      ${if def:received_protocol {with $received_protocol}} \
      ${if def:tls_cipher {($tls_cipher)\n\t}}\
      (Exim $version_number)\n\t\
      id $message_id\
      ${if def:received_for {\n\tfor $received_for}}

define(`_REC_BY_', `$.by $j (envelope-from $f) ($v/$Z)$?r with $r$. id $i$?{tls_version}')


Actually, the Return-Path is standard now, and I don't see any need to add yet another way to specify the envelope recipient. Go read RFC-2821 section 4.4 where this header is defined as a MUST. -- Arik Baratz

But SpamAssassin sometimes runs as an MTA-level filter - example at the top shows SA refusing mail at SMTP time. It should run as such wherever possible, IMO, and when it does, it should reliably determine the envelope. -- MatthewElvey

First implemented in SA 3.0.3, in case you were wondering. See bug ID #3944. -- Thomas Eisenbarth

EnvelopeSenderInReceived (last edited 2009-09-20 23:16:36 by localhost)