emailmarketing.net

SMTP Smuggling — End-of-DATA Discrepancy Spoofing

How mismatched end-of-DATA parsing between MTAs (bare <LF>.<LF> vs standard <CR><LF>.<CR><LF>) lets an attacker smuggle a second spoofed message that inherits the session's authenticated domain and passes SPF/DKIM/DMARC; the Dec 2023 SEC Consult disclosure and the receiver-side fixes.

Foundationalesp-operatorsender

SMTP smuggling is a spoofing attack that exploits the fact that two MTAs in a mail path can disagree about where a message's DATA ends. The base protocol (RFC 5321) terminates DATA with exactly <CR><LF>.<CR><LF> (a dot alone on a line, CRLF-framed). For decades, servers have also tolerated the non-standard bare-<LF> variants — <LF>.<LF>, <LF>.<CR><LF>, <CR>.<CR> — a Sendmail-era leniency that Postfix, Exim and others copied for interoperability. When the sending (outbound) server and the receiving (inbound) server tolerate different subsets of these variants, an attacker who can inject a crafted line-ending sequence into a message body can make the receiver believe DATA has ended mid-message and treat the bytes that follow as new SMTP commands — a second MAIL FROM / RCPT TO / DATA transaction, i.e. a second, fully spoofed message, "smuggled" inside one legitimate SMTP transaction.

It was disclosed publicly by SEC Consult on 18 December 2023 and is one of the more consequential email-spoofing techniques of recent years because of what it defeats: it makes a forged message pass SPF, DKIM, and DMARC. This is primarily a receiver-side vulnerability — the fix lives in the inbound MTA — but senders and ESPs must understand it because when a receiver is vulnerable it silently undermines the DMARC protection those senders rely on to defend their domains. It does not weaken any authentication record you publish; it defeats the enforcement of those records at a vulnerable receiving hop.

The parsing discrepancy

Two roles, two failure modes, and the attack is the composition of one of each:

Role Vulnerable behavior Consequence
Outbound / submission MTA Forwards a message body containing a bare-<LF> dot sequence without normalizing it to <CR><LF> (or without rejecting it) A message is emitted onto the wire carrying an embedded, non-standard end-of-DATA marker
Inbound / receiving MTA Accepts a non-standard sequence such as <LF>.<LF> as a valid end-of-DATA The bytes after it are parsed as fresh SMTP commands rather than message content

Neither behavior is exploitable alone. The outbound server must let the exotic sequence survive onto the wire, and the receiving server must honor it as a terminator. An attacker who controls (or has a free/compromised account on) a lenient outbound service, aimed at a lenient inbound service, can straddle the gap.

Anatomy of a smuggled transaction

An authenticated attacker submits one message through the outbound service. The visible envelope and headers are the attacker's own legitimate (throwaway) address, so the submission is authorized. Inside the DATA payload the attacker plants:

...legitimate-looking body...
<LF>.<LF>                          ← smuggled end-of-DATA (receiver honors it)
MAIL FROM:<admin@victim-domain.example>
RCPT TO:<target@receiver.example>
DATA
From: admin@victim-domain.example
Subject: (spoofed message)
...attacker payload...
<CR><LF>.<CR><LF>                  ← real end-of-DATA

The vulnerable outbound service transmits all of this as the body of the first message, because it did not treat <LF>.<LF> as a terminator. The vulnerable inbound service, reading the same bytes, does treat <LF>.<LF> as the end of the first message — and then interprets MAIL FROM / RCPT TO / DATA as a brand-new transaction. The receiver has now accepted a second message whose From: is admin@victim-domain.example, delivered over the outbound provider's own trusted, authenticated connection.

BDAT / CHUNKING (RFC 3030) is a related lever: because BDAT frames content by an explicit octet count rather than scanning for <CRLF>.<CRLF>, it permits command pipelining that the DATA path forbids, and buggy BDAT handling has been an independent smuggling vector on the inbound side. This is the interop caution flagged in the CHUNKING section of the ESMTP extensions digest.

Why it bypasses SPF, DKIM, and DMARC

The smuggled message is not authenticated in its own right — it inherits the authentication of the outer session. Each mechanism fails for a distinct reason:

Mechanism Why the smuggled message passes
SPF SPF authorizes the envelope MAIL FROM against the connecting IP. The smuggled transaction is delivered from the outbound provider's own IP, which is legitimately in the provider's SPF. The receiver sees a smuggled MAIL FROM from a domain that either passes on that IP or is simply evaluated against trusted infrastructure. SPF never inspects the From: header at all.
DKIM The forged From: domain does not need a valid signature. The attacker signs with a domain they control (which verifies fine), or relies on the receiver not enforcing header-domain alignment — DKIM proves a domain signed some headers, not that the From: domain authorized this message.
DMARC DMARC requires SPF or DKIM to pass and align with the From: domain. The smuggled message achieves alignment because it originates from the legitimate outbound infrastructure the victim domain's records (or the receiver's trust of that provider) already bless — the receiver evaluates it as though the provider sent it on the victim domain's behalf.

The net effect: admin@outlook.com, admin@microsoft.com, or any address at ~1.35 million GMX/Ionos-hosted domains could be spoofed with a passing DMARC verdict at a vulnerable receiver. A domain owner who has done everything right — SPF, DKIM, p=reject DMARC — gains no protection at a receiver that terminates DATA leniently, because the forgery never had to defeat the records; it walked in on a trusted session.

Contrast with DKIM replay: replay reuses a genuinely signed message verbatim to spend a sender's reputation; smuggling manufactures a new message that borrows a session's authentication. Both defeat naive "DMARC passed, therefore trustworthy" reasoning, from opposite directions.

The December 2023 disclosure — affected parties

SEC Consult (Timo Longin) demonstrated the attack against major production infrastructure. The distinction between outbound (fails to sanitize) and inbound (accepts exotic sequences) roles matters — a provider could be exploitable as one, the other, or both.

Party Role reported Notes / status
GMX / Ionos (United Internet) Outbound Enabled smuggling from ~1.35 million hosted domains. Patched 10 Aug 2023.
Microsoft Exchange Online Outbound Spoofing from millions of domains (e.g. outlook.com, microsoft.com). Patched 16 Oct 2023.
Cisco Secure Email (Gateway / Cloud Gateway) Inbound Accepted exotic sequences in the default configuration; Cisco initially declined to change the default, making the receiver-side workaround operator-mandatory.
Apple iCloud, Fastmail, Startmail, Runbox Outbound and/or inbound (varies) Included among affected services in the disclosure.
Postfix, Sendmail, Exim Inbound (and outbound leniency) The MTA software layer; coordinated fixes and workarounds followed.

Disclosure timeline: initial discoveries June 2023 → vendor notifications late July 2023 → GMX (Aug) and Microsoft (Oct) patched → public disclosure 18 Dec 2023.

CVEs were assigned to the open-source MTAs:

CVE Software
CVE-2023-51764 Postfix
CVE-2023-51765 Sendmail
CVE-2023-51766 Exim

Mitigations

The durable fix is strict end-of-DATA enforcement at the receiver: honor only <CR><LF>.<CR><LF>, and neutralize bare newlines before they can be interpreted as terminators. Outbound sanitization (normalizing bare <LF> to <CR><LF> on egress) closes the other half; the large providers deployed exactly this server-side.

Postfix (receiver-side)

Postfix's guidance (postfix.org/smtp-smuggling.html) offers a short-term workaround and a long-term fix. Parameter defaults depend on the Postfix release.

Long-term fix — bare-newline handling (Postfix 3.8.5 / 3.7.10 / 3.6.14 / 3.5.24 and later):

smtpd_forbid_bare_newline = normalize
smtpd_forbid_bare_newline_exclusions = $mynetworks

normalize accepts a bare <LF> from the client but processes it as if <CR><LF> had been sent, while still requiring the standard <CR><LF>.<CR><LF> to end DATA — which defuses <LF>.<LF> smuggling without breaking legacy clients. The stricter reject setting refuses any bare newline outright but risks rejecting some legitimate mail; the $mynetworks exclusion spares trusted internal senders (e.g. local scripts). Later Postfix releases moved the default toward enforcement.

Short-term workaround — block the pipelining/CHUNKING angle:

smtpd_data_restrictions = reject_unauth_pipelining
smtpd_discard_ehlo_keywords = chunking, silent-discard

or, on Postfix 3.8.1+:

smtpd_forbid_unauth_pipelining = yes
smtpd_discard_ehlo_keywords = chunking, silent-discard

smtpd_forbid_unauth_pipelining is enabled by default in Postfix 3.9+; in 3.8.1 / 3.7.6 / 3.6.10 / 3.5.20 it shipped disabled for compatibility. Discarding the chunking EHLO keyword withdraws BDAT, removing the BDAT-based command-pipelining vector — at the cost of the throughput/large-message benefits BDAT would otherwise provide.

Cisco Secure Email (receiver-side)

Switch the listener's handling of non-standard line endings from the vulnerable "Clean" behavior (which rewrites bare CR/LF into CRLF and can create an exploitable sequence for the backend) to "Allow" — pass the bytes through unchanged so a strict backend requiring <CR><LF>.<CR><LF> never sees a spurious terminator. Because the vulnerable value was the default and initial vendor support was lacking, operators had to make this change explicitly.

General receiver checklist

  • Enforce <CR><LF>.<CR><LF> as the only end-of-DATA; reject or normalize bare <CR>/<LF>.
  • Forbid unauthenticated command pipelining; treat the appearance of MAIL FROM/RCPT TO/DATA inside DATA as an attack signal.
  • Withdraw or carefully audit BDAT/CHUNKING on untrusted inbound listeners.
  • Sanitize on egress too: normalize bare newlines so your outbound path can never emit a smuggling primitive that harms a downstream receiver.
  • Keep MTA software current (past the CVE-2023-5176x fixes).

Sender / ESP takeaway

  • You cannot fix this by changing your own DNS records. No SPF, DKIM, or DMARC configuration stops smuggling; it defeats enforcement, not publication. p=reject is still worth having — it protects you everywhere the receiver is patched, which is now the large majority of mailbox-provider volume post-2023.
  • As an ESP running inbound MTAs (FBL intake, abuse@/postmaster@ role addresses, bounce processors, MX for customer domains), you are a receiver and own the receiver-side fix: strict end-of-DATA enforcement, current MTA builds, disciplined BDAT exposure. See abuse desk and outbound monitoring for where these listeners live.
  • As an ESP running outbound MTAs, ensure your submission path normalizes bare newlines so a compromised or hostile customer cannot use your trusted IPs to smuggle spoofed mail from a third party's domain into a vulnerable receiver — the exact abuse the big providers had to patch out. This is continuous with customer domain authentication hygiene and the broader spoofing-abuse surface in the email abuse taxonomy.
  • Understand the residual risk in reporting: a customer or brand you protect may see a spoofed-message report that "passed DMARC," and the explanation may be a vulnerable receiver, not a flaw in their setup. Being able to name SMTP smuggling — and point to the receiver-side fix — is the difference between a correct diagnosis and a wild-goose chase through the sender's DNS.

See also

  • DMARC (introduction) — the alignment logic smuggling borrows to pass.
  • DKIM Replay — the other major attack that defeats "DMARC passed ⇒ trusted."
  • SMTP (RFC 5321) — the <CR><LF>.<CR><LF> end-of-DATA contract that smuggling violates.
  • ESMTP Extensions — PIPELINING and CHUNKING/BDAT, the mechanics the workarounds tighten.
  • SPF · DKIM — why neither, alone, inspects the From: header.
#transport-security#smtp#smuggling#spoofing#spf#dkim#dmarc#cve-2023-51764#sec-consult#end-of-data#bdat#receiver-side