The SMTP protocol, as defined in RFC 5322 and related standards, technically allows for multiple From:
addresses in email headers (distinct from the envelope sender). This feature exists primarily for:
- Mailing list implementations where messages originate from multiple contributors
- Forwarding scenarios where the original sender needs to be preserved
- Specialized notification systems with multiple origin points
While rare, some valid implementations exist:
From: "Support Team" <support@example.com>,
"Billing Department" <billing@example.com>
This format might appear in:
- Collaborative customer support systems
- Multi-department automated notifications
- Certain legacy mailing list managers
Most modern email systems treat multiple From:
headers as suspicious because:
- It's a common spam/phishing technique to obfuscate origin
- Few legitimate senders actually need this functionality
- It complicates authentication (SPF/DKIM/DMARC checks)
Here's how you might detect and handle such messages in Python:
import email
from email.header import decode_header
def has_multiple_from(raw_email):
msg = email.message_from_string(raw_email)
from_headers = msg.get_all('From', [])
# Count distinct addresses
addresses = set()
for header in from_headers:
for part in decode_header(header):
if isinstance(part[0], bytes):
text = part[0].decode(part[1] or 'utf-8')
else:
text = part[0]
addresses.update(re.findall(r'[\w\.-]+@[\w\.-]+', text))
return len(addresses) > 1
When building email processing systems:
- Consider multiple
From:
headers as high-risk indicators - Prefer envelope sender (Return-Path) for authentication
- Log such messages for analysis rather than silently discarding
- Provide clear bounce messages when rejecting
The feature originates from early SMTP implementations (1980s) when:
- Email routing was simpler and more trusted
- Collaborative editing workflows were envisioned differently
- Security considerations were less prominent
While working on an email parsing library recently, I stumbled upon an obscure SMTP behavior that made me pause - the protocol actually allows multiple From:
headers in message bodies (not to be confused with envelope senders). This seems counterintuitive in today's security-conscious email ecosystem.
Received: from mail.example.com (EHLO mail.example.com)
From: admin@example.com
From: support@example.com
Date: Wed, 15 Mar 2023 09:45:12 +0000
Subject: Multiple FROM test
Digging through RFC 5322 and its predecessors reveals this wasn't always an edge case. In early email systems:
- Mail forwarding services needed to preserve original sender information
- Mailing list managers would add administrative addresses while keeping original FROM
- Some gateway systems merged messages from multiple sources
Here's how a mailing list might have used it in the 1990s:
From: original-sender@domain.com
From: list-owner@listserver.com
Sender: list-bounces@listserver.com
Today, this feature is overwhelmingly used for malicious purposes:
- Phishing attacks obscuring true sender identity
- Spam messages attempting to bypass filters
- Email spoofing combined with display name deception
Most modern MTAs and libraries handle this automatically. For example, Python's email parser:
import email
from email.policy import default
msg = email.message_from_file(open('email.eml'), policy=default)
from_addresses = msg.get_all('from', []) # Returns list of all FROM headers
For developers working with email processing:
- Validation: Treat multiple FROM headers as potential security risk
- Parsing: Always use
get_all()
methods when processing headers - Filtering: Consider rejecting or flagging messages with this characteristic
Here's a practical filter example in Node.js:
function validateEmailHeaders(email) {
const fromHeaders = email.headers.get('from');
if (Array.isArray(fromHeaders) && fromHeaders.length > 1) {
throw new Error('Multiple FROM headers detected');
}
// Continue processing...
}
A 2021 study of phishing campaigns found:
Campaign Type | Multiple FROM Usage |
---|---|
CEO Fraud | 17% |
Credential Phishing | 23% |
Malware Distribution | 9% |
The security team at Acme Corp shared their filtering approach:
# Postfix header_checks rule
/^From:.*\nFrom:/ REJECT Multiple FROM headers detected
For systems that must maintain strict RFC compatibility:
- Log all instances for security analysis
- Implement scoring systems rather than binary rejection
- Consider adding X-Headers to note the anomaly
Example scoring implementation:
def score_email(msg):
score = 0
if len(msg.get_all('from', [])) > 1:
score += 5 # Medium risk
if 'sender' not in msg:
score += 3 # No Sender header increases risk
return score