We spent twenty years stacking authentication on top of email. SPF to say which servers may send for a domain. DKIM to sign the message so tampering shows. DMARC to tie the two together and tell receivers what to do when they disagree. It is a lot of machinery, and when it all lines up it answers a real question: did this message actually come from a server the domain owner authorized, unchanged?
In December 2023, Timo Longin at SEC Consult published a technique that walked straight through that stack. He sent mail impersonating addresses at domains whose mail runs through big providers — microsoft.com among them, via Exchange Online — and it arrived with SPF and DMARC both showing pass. Not “the checks were misconfigured.” Not “the domain had a weak record.” The checks ran, evaluated correctly, and returned pass on a forged message. He called it SMTP smuggling, and the reason it works is one of those things that is obvious in retrospect and unsettling once you see it: none of that authentication machinery gets a say in where one email ends and the next begins.
The line that means “I’m done”
SMTP is a conversation. A client connects, says who the mail is from and who it’s to, then says DATA and streams the message body. The body can be any length, so there has to be an agreed signal for “the message is over.” That signal is a line containing a single dot, framed by carriage-return-line-feed on both sides: <CR><LF>.<CR><LF>. The server reads bytes until it sees exactly that sequence, and then it knows the message is done and anything after it is a new command.
That end-of-data marker is the entire ballgame. Everything before it is one email’s content. Everything after it is the next SMTP transaction — a fresh MAIL FROM, RCPT TO, DATA. If two servers ever disagree about what counts as that marker, you have a seam, and a seam is where you smuggle.
Here’s the disagreement. The standard says the terminator is <CR><LF>.<CR><LF>. But servers have spent decades being forgiving about line endings, because clients over the years have been sloppy about them. Some servers will also accept a bare <LF>.<LF>, or a lone <CR>.<CR>, as end-of-data. Others won’t — they hold out for the exact canonical sequence. Neither behavior is crazy on its own. Being liberal in what you accept is practically the unofficial motto of internet protocols. But the moment an outbound server and an inbound server draw that line in different places, an attacker can put a message on the wire that the two of them chop into different pieces.
Two servers, two readings, one forged email
Walk through what the attacker actually does. They have a legitimate account on a provider whose outbound server doesn’t treat the odd sequences as end-of-data and doesn’t clean them up either — it passes them along untouched. Call it the sending side. They compose a single message and bury inside its body a sequence like <LF>.<LF> followed by a complete second SMTP transaction: another MAIL FROM, another RCPT TO, another DATA block containing a spoofed email from, say, the CEO of some company the attacker wants to impersonate. The one constraint: the spoofed domain’s SPF record has to authorize that same provider’s servers — which, for a provider the size of Exchange Online, covers millions of domains.
The sending server looks at that buried <LF>.<LF> and does not treat it as the end of the message — to its strict reading, only <CR><LF>.<CR><LF> ends a message, so that’s just some bytes inside the body. So it relays the whole thing as one email, over its own trusted connection, to the receiving server. The connection is the provider’s genuine outbound server, from the provider’s genuine IP address.
Then the receiving server reads the same bytes — and it’s one of the servers that honors a bare <LF>.<LF> as end-of-data. So at that exact byte, it decides the first message is over. Everything after becomes, in its eyes, a brand-new SMTP command sequence: the smuggled MAIL FROM, the smuggled RCPT TO, the smuggled DATA. It accepts a second email that the sending provider never knew it was sending, addressed however the attacker wrote it, and delivers it. Then the receiver authenticates that second message. SPF asks whether the connecting IP may send for the smuggled sender’s domain — and because that domain’s SPF record authorizes the provider’s servers, the answer is yes. DMARC sees an SPF pass on an aligned domain and passes too; it only needs one. DKIM never gets a vote: the smuggled message carries no valid signature for the spoofed domain, and DMARC doesn’t require one. SPF pass. DMARC pass. On a forgery.
Nobody broke a signature. Nobody guessed a key. The attacker exploited the fact that “where does this email end” is a parsing decision, and two parsers made it differently.
Why the auth stack couldn’t have caught it
This is the part I keep chewing on, because it’s a lesson well beyond email. SPF, DKIM, and DMARC are all defined over a message and an envelope. They assume the framing question is already settled — that everyone agrees on which bytes constitute the message they’re authenticating. They validate the contents of a box. They have nothing to say about who decided where the box’s walls are.
SMTP smuggling attacks the walls, not the contents. By the time SPF and DMARC run, the receiving server has already decided this is a separate message; they check the smuggled envelope against a connection that really did come from an authorized server, and wave the fraudulent message through with it. Every check does its job perfectly and the composite answer is still a lie. It’s the exact shape of HTTP request smuggling, which broke on the same disagreement — front-end and back-end proxies parsing Content-Length and Transfer-Encoding differently and slicing one HTTP stream into two. Same class of bug, different protocol. When two systems in a chain parse framing differently, no amount of authentication downstream saves you, because they’re not even authenticating the same units.
The vulnerabilities got real CVEs against real software: CVE-2023-51764 for Postfix, CVE-2023-51765 for Sendmail, CVE-2023-51766 for Exim — the mail transfer agents behind a very large share of the internet’s mail. Providers including GMX, Microsoft, and Cisco’s Secure Email were shown vulnerable in the disclosure. The scale wasn’t a handful of misconfigured hosts; it was default behavior in the software most mail servers run.
The fix is to stop being generous
The remedy is unglamorous and exactly right: stop accepting non-standard end-of-data. Servers were patched to reject bare newlines in the message stream — Postfix added smtpd_forbid_bare_newline to refuse a lone <LF> where the protocol demands <CR><LF>, and the other MTAs made equivalent changes. In other words, the fix is to be strict about the one sequence that decides where a message ends, and to stop honoring the sloppy shortcuts that decades of lenient parsing had normalized.
That’s the uncomfortable moral. The liberality that kept email working with badly-behaved clients for thirty years — accept a bare newline, don’t be a stickler about carriage returns — is the same liberality that let someone forge past the entire authentication stack. Postel’s law, “be liberal in what you accept,” reads like wisdom until you notice that every place two systems are liberal in slightly different ways is a place an attacker can wedge apart. Framing is not a detail beneath the security layer. Framing is a security layer, and it’s the one nobody was watching because it felt too low-level to matter. It mattered.