Safeguard
Supply Chain Security•

SMTP Abuse From Open Relays to SMTP Smuggling: A Defender's History

SMTP trusted every peer, so abuse ran from open relays to spoofing, STARTTLS stripping and SMTP smuggling. What each fix changed and how to audit a domain.

Safeguard Security Team
48 min read

SMTP was abused for forty years because it was built to trust every peer: any server would relay for anyone, any sender could claim any address, and encryption was optional and silently removable. Each fix closed one door. Relay restrictions (RFC 2505, 1999) ended open relays, SPF, DKIM and DMARC (2006 to 2026) made spoofed domains detectable, MTA-STS and DANE (2015 and 2018) made STARTTLS stripping visible and refusable, and strict line ending handling in Postfix, Sendmail and Exim (December 2023 to January 2024) closed SMTP smuggling.

The defender's lesson is the same each time. The protocol stays permissive for compatibility, so protection lives in configuration you publish in DNS and in server software you keep patched. This post walks the history in order, explains each attack conceptually with the fix it forced, and ends with an end to end audit of your own mail domain. It goes one level deeper than our SMTP explainer, and every date, version and setting below was checked against the RFC, project advisory or provider page linked in Sources.

Key takeaways

  • Open relays ended through operator policy, not protocol change. RFC 2505 (February 1999, BCP 30) said an MTA MUST be able to restrict unauthorized relaying; RFC 5321 (October 2008) says a server that declines to relay SHOULD answer with a 550.
  • Each authentication layer fixed what the previous one could not. SPF checks the envelope sender's IP authorization, DKIM signs content and survives forwarding, and DMARC ties both to the visible From domain and adds policy and reporting.
  • DMARC is now a standards track protocol. RFC 9989 (May 2026) obsoletes RFC 7489, replaces the Public Suffix List with a DNS Tree Walk, adds np, psd and t, and removes pct, rf and ri. Aggregate and failure reporting moved to RFC 9990 and RFC 9991.
  • STARTTLS was strippable from day one, and the RFC said so. RFC 3207 (February 2002) describes deleting the "250 STARTTLS" response. MTA-STS (RFC 8461) and DANE for SMTP (RFC 7672) let a receiving domain tell senders to refuse plaintext, and TLS-RPT (RFC 8460) reports failures.
  • SMTP smuggling was a parsing disagreement between two servers. One service forwarded a non-standard end of data sequence and another accepted it, so one message became two. Postfix added smtpd_forbid_bare_newline, Sendmail 8.18.1 (31 January 2024) enforced CRLF, and Exim stopped accepting dot followed by a bare LF in CRLF mode.
  • The worst mail server bugs cluster in a few classes: debug or test features left reachable, input parsing that reaches a shell or spool file, memory safety in decoders, TLS handling, and state confusion at protocol transitions.
  • Gmail and Yahoo turned best practice into requirements in February 2024. SPF or DKIM for everyone, SPF plus DKIM plus DMARC for bulk senders, spam rates under 0.3%, and one-click unsubscribe for marketing mail.
  • Mail servers are open source components. Postfix, Exim, Sendmail and OpenSMTPD inside your images need the same version tracking as any library.

A dated timeline of SMTP abuse and defence

Every row below was checked against the linked primary source. Dates are publication dates of the RFC or the project's own advisory.

DateEventWhat it meant for defendersSource
August 1982RFC 821 defines SMTPServers relay mail between hosts; no sender authenticationRFC 821
November 1988Internet worm spreads partly through sendmail's non-standard "debug" commandFirst large lesson that mail servers are internet facing attack surfaceRFC 1135 (December 1989)
January 1999RFC 2487 defines STARTTLS for SMTPOpportunistic encryption arrives, opt-in and downgradableRFC 2487
February 1999RFC 2505, BCP 30, anti-spam recommendationsMTAs MUST be able to refuse unauthorized relayingRFC 2505
February 2002RFC 3207 replaces RFC 2487Spells out that deleting "250 STARTTLS" is a man-in-the-middle attackRFC 3207
April 2006RFC 4408, SPF, published as ExperimentalDomains can list IPs allowed to use them in the envelope senderRFC 4408
May 2007RFC 4871, DKIM, Standards Track; DomainKeys (RFC 4870) made HistoricDomains can sign messages with a key published in DNSRFC 4871
October 2008RFC 5321 replaces RFC 2821Declining to relay should return 550; bare LF dot LF MUST NOT end dataRFC 5321
March 2011STARTTLS plaintext command injection published (CVE-2011-0411)Commands sent before the TLS switch could be executed after itPostfix write-up
September 2011RFC 6376, current DKIMClarified DKIM, including risks of the l= body length tagRFC 6376
April 2014RFC 7208, SPF on the Standards TrackTen DNS lookup limit, permerror on excessRFC 7208
March 2015RFC 7489, DMARC, InformationalPolicy and reporting tied to the visible From domainRFC 7489
October 2015RFC 7672, DANE for SMTPDNSSEC signed TLSA records make TLS to an MX mandatory and authenticatedRFC 7672
September 2016RFC 7960, DMARC and indirect mail flowsDocuments why mailing lists and forwarders break under strict DMARCRFC 7960
October 2017CISA BOD 18-01US federal agencies must offer STARTTLS and reach DMARC p=reject within a yearCISA
January 2018RFC 8314Implicit TLS preferred for mail submission and accessRFC 8314
February 2018Exim CVE-2018-6789, buffer overflow in base64 decodingMemory safety in a decoder reachable from the networkExim advisory
September 2018RFC 8461 (MTA-STS) and RFC 8460 (TLS-RPT)HTTPS published policy against STARTTLS stripping, plus failure reportsRFC 8461, RFC 8460
June 2019Exim CVE-2019-10149, versions 4.87 to 4.91Reported possible remote exploit; Exim 4.92 not affectedExim advisory
July 2019RFC 8617, ARC, ExperimentalIntermediaries can record and seal authentication resultsRFC 8617
September 2019Exim CVE-2019-15846, TLS SNI handlingEvery Exim up to 4.92.1 accepting TLS was affectedExim advisory
January and February 2020OpenSMTPD errata in OpenBSD 6.6An incorrect check and an out of bounds read let commands run as rootOpenBSD errata
September 2020M3AAWG Email Authentication Recommended Best PracticesIndustry checklist for senders, intermediaries and receiversM3AAWG
July 2021RFC 9091, PSD DMARC, ExperimentalPublic suffix operators can publish DMARC policyRFC 9091
18 to 22 December 2023SMTP smuggling published; Postfix ships fixes on 22 DecemberParsing differentials across two mail services enable spoofing that passes SPFPostfix
24 December 2023CVE-2023-51764 (Postfix), CVE-2023-51765 (Sendmail), CVE-2023-51766 (Exim)Fixes and workarounds land across major MTAsCERT/CC VU#302671
16 January 2024CERT/CC publishes VU#302671Coordinated note covering email services and appliancesCERT/CC
21 January 2024Postfix 3.8.5, 3.7.10, 3.6.14, 3.5.24Normalize mode protects without rejecting bare LFPostfix
31 January 2024Sendmail 8.18.1Only CRLF accepted as line end; pipelining before replies refusedSendmail release notes
1 February 2024Gmail sender requirements take effect; Yahoo begins enforcementAuthentication, low spam rates and one-click unsubscribe become conditions of deliveryGoogle, Yahoo
May 2026RFC 9989, 9990, 9991 obsolete RFC 7489DMARC becomes Standards Track with a DNS Tree WalkRFC 9989

Attack classes and the defence each one forced

The table below compares the major SMTP abuse classes by what the attacker needs, what the attack breaks and what fixed it. It is the one table to keep if you are explaining mail security to a new team member.

Attack classAttacker needsWhat it breaksPrimary fixWhere the fix livesResidual risk
Open relay abuseAny internet connectionYour server's reputation and resourcesRelay restrictions (RFC 2505)MTA configurationCompromised submission accounts relay just as well
Envelope sender spoofingAny SMTP serverBounce path and SPF identitySPF (RFC 7208)DNS TXT at the sending domainBreaks on forwarding; does not protect the visible From
Content tampering and From spoofingAny SMTP serverThe message the user readsDKIM (RFC 6376) plus DMARC (RFC 9989)DNS and signing on outbound serversLookalike domains are untouched
Indirect flow breakageNothing; mailing lists do it by designLegitimate mail under strict DMARCARC (RFC 8617), From rewriting at listsIntermediary and receiverARC trust is receiver specific
STARTTLS strippingA network position between serversConfidentiality and integrity in transitMTA-STS (RFC 8461) or DANE (RFC 7672)DNS, HTTPS policy host, DNSSECFirst contact before a policy is cached
STARTTLS command injectionA network positionTLS session integrityDiscard buffered plaintext at the TLS switchMTA codeSame class can recur in any STARTTLS protocol
SMTP smugglingAn account at one mail serviceMessage boundaries and SPF based DMARCStrict end of data parsingMTA code and settings at both endsAny parser differential between hops
Memory and input bugs in MTAsNetwork access to port 25The host itselfPatches from the projectPackage and image updatesUnpatched copies in old images and appliances

Why was SMTP designed to relay for anyone, and how did open relays end?

The original design assumption

RFC 821, published in August 1982, describes a mail system where hosts pass messages along a path until they reach the destination. The early internet was a small network of institutions that knew each other, and relaying was a feature: if your host could not reach the destination directly, another host would carry the message for you. RFC 821 even supported explicit source routes, so a sender could name the chain of relays.

Nothing in that design asked "who are you, and should I carry mail for you?" A server that accepted a message for a domain it did not host simply looked up the next hop and forwarded it. That is what "open relay" means: a server that will accept mail from any client to any recipient and pass it on.

What went wrong

Once commercial internet access arrived, open relays became free infrastructure for bulk unsolicited mail. RFC 2505, published as Best Current Practice 30 in February 1999, describes the pattern plainly: spammers used third party relays to send mail out to receivers, the relay owner paid for the bandwidth and took the reputation damage, and the receivers could not easily trace the sender. The RFC calls unauthorized relay usage "theft of the relay's resources."

The first major security lesson about mail servers came earlier. The November 1988 internet worm, analysed in RFC 1135 (December 1989), spread partly through a non-standard "debug" command in sendmail that remote hosts could reach. RFC 1135 lists "patching out the debug command in sendmail" among the fixes. The relevant point for this history is that a mail server sits on the open internet by design, so any feature it exposes, including test and debug paths, is attack surface.

How open relays ended

Open relays did not end with a protocol change. They ended because operators changed defaults and because receivers stopped trusting relays that stayed open.

RFC 2505 set out the MTA requirements. An MTA MUST be able to restrict unauthorized use as a mail relay, and MUST be able to authorize relaying based on the client's IP address and on the recipient domain. Its rule set is short: accept to relay if the recipient domain is one you host or back up, accept if the client is one of yours, otherwise refuse. It also asks that MTAs SHOULD log anti-relay actions so operators can see abuse.

RFC 5321, the current SMTP specification (October 2008), keeps relaying in the protocol but makes refusal normal. Section 3.6.2 says a relay "may accept or reject the task of relaying the mail in the same way it accepts or rejects mail for a local user," and that a server declining to relay for policy reasons SHOULD return a 550 reply. Section 3.6.1 lets servers ignore source routes and decline to act as relays for them.

The modern pattern has three parts:

  1. Port 25 accepts mail only for domains you host. Anything else gets a 5xx relay denied reply.
  2. Your own users submit mail on a separate submission service with authentication. RFC 8314 (January 2018) recommends implicit TLS for submission and access protocols, so credentials never cross the network in plaintext.
  3. Trusted networks are small and explicit. In Postfix that is mynetworks; in Exim, relay_from_hosts; in Sendmail, the access database.

The residual risk is worth naming. A server that only relays for authenticated users is still a relay for anyone who steals a user's password. Modern open relay abuse mostly looks like compromised accounts, which is why outbound rate limits and per account monitoring matter as much as relay rules.

How did spoofing lead to SPF, DKIM and DMARC, in order and why was each needed?

RFC 5321 is blunt about the core weakness. Section 7.1 says SMTP mail "is inherently insecure" because casual users can talk directly to servers and construct messages that appear to come from somewhere else, and that real mail security lies only in end to end methods. The three authentication layers built since 2006 do not make SMTP secure; they make specific kinds of forgery detectable.

Two identities, two places to lie

A message carries two sender identities. The envelope sender, the address in the MAIL FROM command (often called RFC5321.MailFrom), is where bounces go. The header From, the address the user sees (RFC5322.From), is what people trust. They can differ legitimately, for example when a mailing service sends on behalf of a brand, and SMTP never checks either.

SPF: who may send for a domain's envelope sender

SPF was first published as RFC 4408 in April 2006 with Experimental status, and moved to the Standards Track as RFC 7208 in April 2014. A domain publishes a TXT record listing the IP addresses and hosts allowed to use it in MAIL FROM and HELO. The receiver checks the connecting IP against that list.

SPF solved one problem: bounce spoofing and casual envelope forgery. It left two gaps:

  • It checks the envelope, not the visible From. An attacker can use their own domain in MAIL FROM, pass SPF, and put your domain in the header From.
  • It breaks on forwarding. When a forwarder passes a message on, the connecting IP is the forwarder's, not yours.

RFC 7208 also sets an operational limit that still catches teams out. The mechanisms that cause DNS queries (include, a, mx, ptr, exists and the redirect modifier) are limited to 10 per evaluation, and exceeding the limit MUST return "permerror." A domain that adds one more marketing service to its SPF record can silently move from pass to permerror.

DKIM: a signature that travels with the message

DKIM was published as RFC 4871 in May 2007, which also made the earlier DomainKeys (RFC 4870) Historic. The current specification is RFC 6376 (September 2011). The sending server signs selected header fields and the body with a private key, and the receiver fetches the public key from DNS at selector._domainkey.domain.

DKIM fixed the forwarding problem, because the signature stays valid as long as the signed content is not changed, no matter which IP delivers it. It still did not tie anything to the visible From. A valid signature from d=attacker.example on a message whose header From says your domain is a valid DKIM pass, just for the wrong domain.

RFC 6376 also warns about the l= body length tag, which limits how much of the body the signature covers. Its Section 8.2 explains that content appended beyond the signed length is not protected. The defender's rule is simple: do not use l= on outbound signatures. Our DKIM selectors explainer covers key rotation in depth.

DMARC: alignment, policy and reporting

DMARC was published as RFC 7489 in March 2015 as an Informational RFC through the Independent Submissions stream. It added the piece the other two lacked: alignment with the header From. A message passes DMARC when SPF passes for a domain aligned with the header From, or DKIM passes with a d= domain aligned with the header From. The domain owner publishes a policy at _dmarc.domain saying what receivers should do with failures (none, quarantine or reject) and where to send aggregate reports.

In May 2026, RFC 9989 obsoleted RFC 7489 and RFC 9091 and put DMARC on the Standards Track. According to its Appendix C:

  • Organizational Domain discovery changed. Reliance on a Public Suffix List is replaced by a DNS Tree Walk, which also absorbs public suffix domain policy discovery from RFC 9091.
  • Tags added: np (policy for non-existent subdomains), psd (flag for public suffix domains) and t (a replacement for some pct functionality).
  • Tags removed: pct, rf and ri.
  • Reporting moved to RFC 9990 (aggregate) and RFC 9991 (failure).
  • Domain owner guidance expanded, including the statement that domains for general purpose email SHOULD NOT deploy p=reject without first measuring the impact.

RFC 9989 also notes an interoperability risk during the transition: a receiver still running RFC 7489 logic with a Public Suffix List might find a different Organizational Domain than one using the Tree Walk. It says this is avoided by strict alignment and by publishing explicit DMARC records for every author domain you use. Our posts on what changed in RFC 9989 and relaxed versus strict alignment go further.

Why the order mattered

LayerYear first publishedWhat it authenticatesWhat it cannot do alone
SPF2006 (Standards Track 2014)The connecting IP for the envelope sender or HELO domainProtect the visible From; survive forwarding
DKIM2007 (current RFC 2011)A domain's signature over headers and bodySay which domain the user should trust
DMARC2015 (Standards Track 2026)Alignment of SPF or DKIM with the header From, plus policyStop lookalike domains or compromised accounts

Each layer was a reaction to the gap in the last one. That history explains a common audit finding: a domain with SPF and DKIM configured but no DMARC record has done most of the work and gets almost none of the spoofing protection, because nothing tells receivers to reject a message whose visible From does not align.

Where the guidance disagrees on p=reject

The two current references take different positions, and defenders should know both. The M3AAWG Email Authentication Recommended Best Practices (September 2020) says policy statements should be p=reject where possible and treats p=none and partial pct as transitional states. RFC 9989 Section 7.4 says domains that host users who might post to mailing lists SHOULD NOT publish p=reject, and that domains wishing to do so SHOULD first publish p=none for at least a month, then p=quarantine for an equally long period, and compare results. It also says domains publishing p=reject MUST NOT rely only on SPF and MUST apply valid DKIM signatures.

These positions reconcile in practice. Transactional and marketing domains that never post to mailing lists can and should reach p=reject. A domain where staff use their mailbox for open source mailing lists may be better served at p=quarantine with a separate sending subdomain at p=reject.

What is STARTTLS stripping, and how do MTA-STS and DANE respond?

How opportunistic TLS works

STARTTLS for SMTP was defined in RFC 2487 (January 1999) and replaced by RFC 3207 (February 2002). A server lists STARTTLS in its EHLO response, the client sends the STARTTLS command, and both switch to TLS on the same connection. If the server does not offer STARTTLS, the client sends in plaintext. Server to server mail on port 25 rarely validated certificates, because there was no agreed way to know what name the certificate should match or whether the receiving domain intended TLS at all.

Stripping in concept

The weakness is that the offer itself travels in plaintext. RFC 3207 describes it in its security considerations: an attacker in the path can delete the "250 STARTTLS" line from the server's response, so the client never tries TLS. Another form lets the offer through but interferes with the switch. RFC 8461 adds the other variant: an attacker who can redirect the session, for example by overwriting the MX lookup result, can send the client to a server they control. Without a policy saying "this domain always uses TLS with a valid certificate for these MX hosts," the sending server has no reason to object.

RFC 3207's own answer was that clients and servers MUST be configurable to require TLS for selected hosts. That works between two partners who arrange it, not across the internet. MTA-STS and DANE are the two ways to publish that requirement at scale.

MTA-STS (RFC 8461, September 2018)

MTA-STS lets a receiving domain publish a policy through DNS and HTTPS:

  • A TXT record at _mta-sts.example.com with v=STSv1 and an id that changes whenever the policy changes.
  • A policy file at https://mta-sts.example.com/.well-known/mta-sts.txt, served with a valid web PKI certificate, containing version: STSv1, a mode of enforce, testing or none, one mx line per allowed MX pattern, and max_age in seconds, at most 31557600 (one year).

A sending server that supports MTA-STS fetches and caches the policy. In enforce mode it refuses to deliver if it cannot negotiate TLS with a valid certificate to an MX that matches the policy. In testing mode it delivers anyway and reports the failure.

RFC 8461 Section 10.2 is honest about the gap. An attacker who can block DNS during the first policy discovery can make the domain look as if it has no policy. The cache is the defence: the RFC asks for long max_age values and for senders to refresh policies in the background rather than waiting for expiry.

DANE for SMTP (RFC 7672, October 2015)

DANE uses DNSSEC instead of the web PKI. The receiving domain publishes TLSA records at _25._tcp.<mx-host> saying which certificate or key the MX will present. Because the records are DNSSEC signed, an attacker cannot forge them, and because their presence is authenticated, a sender that supports DANE knows TLS is mandatory.

RFC 7672 recommends DANE-EE(3) SPKI(1) SHA2-256(1) records, a hash of the server's public key, with DANE-TA(2) Cert(0) SHA2-256(1) records as a second choice, and explains why the PKIX usages (0 and 1) are not suited to SMTP. It also requires validating resolvers, not stub resolvers trusting an upstream.

TLS reporting (RFC 8460, September 2018)

TLS-RPT lets a domain ask senders for reports of TLS successes and failures, each covering a full UTC day. You publish v=TLSRPTv1; rua=mailto:... (or an HTTPS endpoint) at _smtp._tls.example.com. Reports arrive as JSON (application/tlsrpt+json, or gzip compressed). This is what makes MTA-STS testing mode useful: you see which senders fail before you switch to enforce.

MTA-STS versus DANE: a decision table

QuestionMTA-STSDANE
Trust anchorWeb PKI certificate on the policy host and on each MXDNSSEC chain to your zone
Needs DNSSECNoYes, on the MX host's zone
Extra infrastructureAn HTTPS host at mta-sts.<domain>TLSA records kept in step with key changes
First contact protectionNo, trust on first use with cachingYes, if the sender validates DNSSEC
Main operational riskExpired certificate on an MX, or policy left in testing foreverKey rollover without updating TLSA first
Works with hosted mailbox providersUsually, through a CNAME to the providerOnly if the provider's MX zone is signed and publishes TLSA

Many domains publish both. Senders that support DANE use it; others fall back to MTA-STS.

STARTTLS command injection (CVE-2011-0411)

A related class is worth recording because it is a state bug, not a protocol flaw. Wietse Venema's March 2011 write-up describes how several SMTP implementations, including Postfix before the fix, would execute commands that a man in the middle injected during the plaintext phase as if they had arrived after the switch to TLS. The fix was to discard any buffered plaintext input when TLS starts. The write-up notes that POP3, IMAP, NNTP and FTP have the same mid-session switch and can carry the same bug. The lesson recurs below with SMTP smuggling: transitions inside a protocol stream are where implementations disagree.

What was SMTP smuggling (December 2023), and what did mail server projects change?

The mechanism in concept

SMTP ends the message data with a line containing only a period, the sequence <CRLF>.<CRLF>. RFC 5321 Section 4.1.1.4 says the bare line feed form <LF>.<LF> MUST NOT be treated as equivalent. Section 2.3.8 says conforming implementations MUST NOT recognize other line terminators.

In practice, many servers accepted a bare LF as a line ending for compatibility with old clients. Postfix's own analysis traces this to Sendmail many decades ago, with Postfix and Exim following for compatibility.

SMTP smuggling needs two mail services that disagree:

  1. Service A, where the attacker has an account, accepts a message containing a non-standard end of data sequence and forwards it verbatim.
  2. Service B, the recipient's server, treats that non-standard sequence as the real end of data.

Service B then reads whatever followed as new SMTP commands and a second message. Because the connection came from service A's IP address, the second message passes SPF for any domain hosted at service A, and therefore can pass SPF based DMARC. CERT/CC's note VU#302671 adds that email security gateways analysing the stream can be confused the same way.

That is the whole idea: a message boundary disagreement between two parsers. No payloads are needed to understand the defence. Either service A must normalise or reject non-standard line endings before forwarding, or service B must refuse to treat them as end of data.

What happened, and when

According to the Postfix project's page, the research was published on 18 December 2023, days before a long holiday change freeze, and the details had not reached Postfix maintainers beforehand. The Postfix timeline from that page:

DatePostfix action
18 December 2023Learns of the publication
19 December 2023Researches and implements a fix
21 December 2023Fixes problems found in validation with BDAT and XCLIENT
22 December 2023Publishes Postfix 3.8.4, 3.7.9, 3.6.13 and 3.5.23
24 December 2023CVEs assigned for Postfix, Exim and Sendmail; distributions ship updates
21 January 2024Publishes 3.8.5, 3.7.10, 3.6.14 and 3.5.24 with a mode that prevents smuggling without rejecting bare LF

CERT/CC published VU#302671 on 16 January 2024 (last revised 31 January 2024) listing CVE-2023-51764 for Postfix, CVE-2023-51765 for Sendmail and CVE-2023-51766 for Exim.

What each project changed

Postfix. The short term workaround, for all versions, rejects unauthorized command pipelining and hides the CHUNKING extension:

# main.cf, short-term workaround from postfix.org/smtp-smuggling.html
smtpd_data_restrictions = reject_unauth_pipelining
smtpd_discard_ehlo_keywords = chunking, silent-discard

The long term fix, in 3.8.5, 3.7.10, 3.6.14, 3.5.24 and later, is:

# main.cf, long-term fix
smtpd_forbid_bare_newline = normalize
smtpd_forbid_bare_newline_exclusions = $mynetworks

normalize requires the standard end of data sequence while still accepting bare LF inside a message and treating it as CRLF. reject refuses any command or message with a bare LF and, in Postfix's words, is more likely to reject legitimate mail. The older yes value is an alias for normalize. Postfix says smtpd_forbid_unauth_pipelining is enabled by default from Postfix 3.9, and that disabling CHUNKING is still prudent.

Sendmail. The 8.18.1 release notes, dated 31 January 2024, say Sendmail now accepts only CRLF as the end of a line, and therefore only CRLF . CRLF as the end of a message. It also refuses bare CR or LF except as CRLF, and refuses "transaction stuffing" by making clients wait for HELO, EHLO and DATA responses before sending more commands. New srv_features options (O, U, G, F) can turn these off, with the advice to do so only for trusted networks.

Exim. Exim's ChangeLog entry JH/12 records that Exim now refuses a line of dot followed by a bare LF as end of DATA unless it is operating in LF-only mode detected from the first header line, citing "smtp smuggling." Check your distribution's Exim package changelog for the exact backport it carries.

Postfix also published a separate note that some test tools make false vulnerability claims based on attack patterns that are not viable. If a scanner flags your patched Postfix, read that note before changing settings.

The lesson

SMTP smuggling did not break any single server's logic. It broke the assumption that two compliant looking servers agree on where one message ends. HTTP request smuggling taught the same lesson for proxies. The defence is strict parsing at every hop you control, and patching both your inbound MX and any relay or gateway that forwards mail onward.

What were the biggest mail server vulnerabilities, by class?

The goal here is pattern recognition, not exploit detail. Every row comes from the project's own advisory or errata page.

ClassExample (project advisory)DateAffectedWhat the advisory says to do
Debug or test feature reachable remotelySendmail "debug" command used by the internet wormNovember 1988Sendmail of the timeRemove the debug command (RFC 1135)
State confusion at a TLS transitionSTARTTLS plaintext command injection, CVE-2011-0411March 2011Postfix and several other implementationsDiscard plaintext buffered before the TLS switch; upgrade
Memory safety in a decoderExim CVE-2018-6789, buffer overflow in base64d()February 2018Exim before the fixUpgrade; no mitigation known at the time
Remotely reachable flaw with few details releasedExim CVE-2019-10149, reported as a possible remote exploitJune 2019Exim 4.87 to 4.91Upgrade; Exim 4.92 not affected
TLS handshake parsingExim CVE-2019-15846, SNI handlingSeptember 2019All Exim up to 4.92.1 accepting TLSUpgrade; disabling TLS listed as not recommended
Incorrect input check reaching mail deliveryOpenSMTPD, OpenBSD 6.6 errata 01930 January 2020smtpd in OpenBSD 6.6Apply the source patch
Out of bounds read affecting the spool envelopeOpenSMTPD, OpenBSD 6.6 errata 02124 February 2020smtpd in OpenBSD 6.6Apply the source patch
Protocol parsing differentialSMTP smuggling, CVE-2023-51764/51765/51766December 2023Postfix, Sendmail, Exim and hosted servicesUpgrade and enable strict end of data handling

Three patterns stand out for defenders.

The bug is often in a feature you do not use. Exim's CVE-2019-15846 affected any server accepting TLS. Many mail servers enable optional authentication mechanisms, proxy protocol support or lookup types by default. Turning off what you do not need shrinks the code an attacker can reach.

Advisories leak before release. Exim's CVE-2019-10149 page records that details leaked and the coordinated release was moved forward to 5 June 2019. Its CVE-2018-6789 page notes that a distribution broke the embargo. Plan to patch mail servers on short notice, not on a monthly cycle.

The mail server is rarely only on your MX. Appliance images, container images for application mailers, monitoring hosts with a local MTA for alerts and CI images often carry Postfix or Exim as a dependency. These copies are the ones nobody patches.

How do ARC and BIMI fit?

ARC: keeping authentication results across intermediaries

ARC, the Authenticated Received Chain, was published as RFC 8617 in July 2019 with Experimental status. It addresses the problem RFC 7960 documented in 2016: mailing lists and forwarders modify messages (subject tags, footers) or resend them from their own IPs, which breaks DKIM and SPF and therefore DMARC.

ARC lets each intermediary record what it saw. At each hop it adds three header fields with the same instance number:

  • ARC-Authentication-Results records the SPF, DKIM and DMARC results the intermediary observed.
  • ARC-Message-Signature is a DKIM-like signature over the message as the intermediary passed it on.
  • ARC-Seal signs the ARC headers themselves, chaining this hop to earlier ones, and carries a chain validation status (cv).

Instance numbers run from 1 to 50. A final receiver that trusts a given intermediary can use the sealed results to override a DMARC failure caused by that intermediary's changes.

ARC does not prove a message is legitimate. It proves what a named intermediary claims it saw. Its value depends on the receiver's list of trusted sealers, which is local policy. M3AAWG's checklist asks intermediaries to implement ARC and receivers to make use of ARC headers.

BIMI: a display signal on top of enforcement

BIMI, Brand Indicators for Message Identification, lets a domain publish a logo that supporting mailbox providers may show next to authenticated mail. According to the BIMI Group's FAQ, you publish a TXT record at default._bimi.<domain> pointing to an SVG logo and optionally a mark certificate (a VMC or CMC). BIMI requires DMARC alignment and enforcement, meaning p=quarantine or p=reject and not p=none or a partial percentage. The FAQ says plainly that BIMI does not change delivery; it is a display signal.

For defenders, BIMI matters for one reason: it gives marketing teams a reason to fund DMARC enforcement. The security benefit comes from the enforcement, not the logo.

How do you audit your mail domain end to end?

This walkthrough checks every published record and the live behaviour of your MX hosts. Replace example.com with your domain. All commands are read only.

Step 1: list your MX hosts

dig +short MX example.com

Write down every host. Each one needs TLS, current software and, if you use DANE, TLSA records.

Step 2: check SPF and count lookups

dig +short TXT example.com | grep -i "v=spf1"

Confirm there is exactly one SPF record (RFC 7208 returns permerror for more than one). Count include, a, mx, ptr, exists and redirect terms, following each include recursively. The total must stay at 10 or below. Domains that never send mail should publish v=spf1 -all, as M3AAWG recommends.

Step 3: check DKIM selectors

dig +short TXT selector1._domainkey.example.com

You need the selector names from your own outbound headers (s= in the DKIM-Signature field). Confirm each active selector has a key and that retired selectors are removed or emptied. Check that outbound signatures do not use l=.

Step 4: check DMARC

dig +short TXT _dmarc.example.com
dig +short TXT _dmarc.mail.example.com

Look for p=, sp= and, under RFC 9989, np= for non-existent subdomains. Confirm rua= points to a mailbox or service that someone actually reads. If you still use pct, plan to move to t as receivers adopt RFC 9989. Publish explicit DMARC records for each author domain and subdomain you send from, since RFC 9989 says this avoids differences between Tree Walk and Public Suffix List receivers.

Step 5: check MTA-STS

dig +short TXT _mta-sts.example.com
curl -sS https://mta-sts.example.com/.well-known/mta-sts.txt

Confirm the TXT record starts with v=STSv1, the policy file is served over HTTPS with a valid certificate as text/plain, every MX from step 1 matches an mx: line, mode is enforce once reports are clean, and max_age is long (weeks or more, at most 31557600).

Step 6: check TLS reporting

dig +short TXT _smtp._tls.example.com

Expect v=TLSRPTv1; rua=mailto:... or an HTTPS endpoint. Then confirm reports are actually arriving and being read.

Step 7: check DANE, if your zone is signed

dig +dnssec +short TLSA _25._tcp.mx1.example.com
dig +short DS example.com

Confirm the MX host's zone is signed, TLSA records exist, and they match the key the server presents. Plan TLSA updates before every certificate or key change.

Step 8: check STARTTLS and the certificate on each MX

openssl s_client -starttls smtp -connect mx1.example.com:25 -servername mx1.example.com -brief </dev/null

Confirm the certificate is valid, unexpired and matches the MX name, and that the negotiated protocol is TLS 1.2 or later. CISA's BOD 18-01 required agencies to disable SSLv2, SSLv3, 3DES and RC4 on mail servers, a reasonable floor for anyone.

Step 9: confirm relay is refused

From a host outside your network, open an SMTP session to each MX and attempt a recipient at a domain you do not host. You should get a 5xx reply such as 550 or 554 relay denied, as RFC 5321 Section 3.6.2 expects. Only test servers you operate.

Step 10: check MTA versions and smuggling settings

# Postfix
postconf mail_version
postconf smtpd_forbid_bare_newline smtpd_forbid_unauth_pipelining smtpd_discard_ehlo_keywords

# Exim
exim -bV | head -1

# Sendmail
sendmail -d0.1 -bv root </dev/null | head -1

# Debian and Ubuntu package view
dpkg -l | grep -E "postfix|exim4|sendmail|opensmtpd"

# RHEL and Fedora package view
rpm -qa | grep -E "postfix|exim|sendmail|opensmtpd"

For Postfix, compare mail_version against 3.8.5, 3.7.10, 3.6.14 or 3.5.24 and later, or your distribution's backported package, and confirm smtpd_forbid_bare_newline is normalize or reject on internet facing listeners. For Sendmail, confirm 8.18.1 or later. For Exim, confirm your package includes the end of DATA change.

Step 11: check BIMI, if marketing wants it

dig +short TXT default._bimi.example.com

Only meaningful once DMARC is at enforcement.

Step 12: find the mail servers you forgot

Search container images and hosts for MTA packages that are not your MX: alerting hosts, application images that install a local mailer, appliance images. These are the copies that miss advisories.

Audit checklist summary

Record or checkLocationPass condition
MXexample.com MXAll hosts known and owned
SPFexample.com TXTOne record, 10 or fewer lookup terms, -all on non-sending domains
DKIMselector._domainkey.example.comActive selectors have keys; no l= on signatures
DMARC_dmarc.example.comEnforcement where safe; rua read; explicit records for subdomains
MTA-STS_mta-sts TXT and policy fileenforce, all MX listed, long max_age
TLS-RPT_smtp._tls TXTReports arrive and are read
DANE_25._tcp.<mx> TLSAMatches the live key; zone signed
STARTTLSEach MX on port 25Valid certificate, TLS 1.2 or later
RelayEach MX5xx for external recipients
MTA versionEach host and imagePatched for CVE-2023-51764/51765/51766 and later advisories

What changed in the 2024 large mailbox provider sender requirements?

Gmail and Yahoo published requirements that took effect in February 2024. The details below come from each provider's own page.

Gmail

Google's sender guidelines say that starting 1 February 2024, all senders to Gmail accounts must:

  • Set up SPF or DKIM.
  • Have valid forward and reverse DNS (PTR) for sending IPs.
  • Use a TLS connection for transmitting email.
  • Keep spam rates reported in Postmaster Tools below 0.3%.
  • Format messages according to RFC 5322.
  • Not impersonate Gmail From headers; Google says Gmail will use a DMARC quarantine enforcement policy.

Senders of more than 5,000 messages a day to Gmail accounts must also set up both SPF and DKIM, publish DMARC (a policy of none is allowed), align the header From with either the SPF or DKIM domain for direct mail, and support one-click unsubscribe for marketing and subscribed messages.

Yahoo

Yahoo's sender best practices page says enforcement began in February 2024 and was rolled out gradually through the first half of the year. All senders must authenticate with SPF or DKIM at minimum, keep spam rates below 0.3%, have valid forward and reverse DNS, and comply with RFC 5321 and RFC 5322. Bulk senders must implement both SPF and DKIM, publish a valid DMARC policy of at least p=none with DMARC passing (relaxed alignment is acceptable, and a rua tag is strongly recommended), support one-click unsubscribe through a List-Unsubscribe header (the RFC 8058 POST method is highly recommended), show a visible unsubscribe link and honour unsubscribes within 2 days.

Side by side

RequirementGmail, all sendersGmail, over 5,000 a dayYahoo, all sendersYahoo, bulk senders
SPF or DKIMRequiredBoth requiredRequiredBoth required
DMARCNot requiredRequired, p=none allowedStrongly urgedRequired, at least p=none, must pass
From alignmentNot statedRequired for direct mailNot statedRequired, relaxed acceptable
Forward and reverse DNSRequiredRequiredRequiredRequired
TLS for transmissionRequiredRequiredNot stated on the pageNot stated on the page
Spam rateBelow 0.3%Below 0.30%Below 0.3%Below 0.3%
One-click unsubscribeNot statedRequired for marketing and subscribed mailNot statedRequired; honour within 2 days

What it changed for defenders

Before 2024, DMARC was a security project that competed for priority. After February 2024, missing authentication became a delivery problem that revenue teams noticed. The requirements are still minimal from a security view (p=none is enough), so the security work of moving to enforcement remains yours.

Common mistakes

  • Stopping at p=none. It satisfies Gmail and Yahoo bulk rules and gives reports, but tells receivers to do nothing with spoofed mail. Plan the move to quarantine and reject using RFC 9989's staged approach.
  • Relying on SPF alone under p=reject. RFC 9989 says such domains MUST apply DKIM signatures, because SPF fails on forwarding.
  • Breaking the SPF lookup limit. Each new mail service adds an include. Past 10 lookup terms, SPF returns permerror and your DMARC pass depends on DKIM alone.
  • Leaving MTA-STS in testing for years. Testing mode reports but does not protect. Read the TLS-RPT reports, fix failures, then switch to enforce.
  • Rotating MX certificates or keys without updating TLSA. Senders that validate DANE will refuse delivery. Publish the new TLSA record before the key changes.
  • Patching the MX and forgetting the relays. SMTP smuggling needed a forwarding hop. Outbound relays, smart hosts and gateways need the same fixes.
  • Using smtpd_forbid_bare_newline = reject everywhere without testing. Postfix warns it is more likely to reject legitimate mail. normalize with mynetworks excluded is the documented default recommendation.
  • Treating ARC as authentication. ARC tells you what an intermediary claims. Trust it only for intermediaries you have chosen to trust.
  • Assuming hosted mail removes MTA patching. Application images, alerting hosts and appliances often run a local Postfix or Exim nobody tracks.
  • Using DKIM l= tags. Content past the signed length is unprotected.

FAQ

What is an open relay in SMTP?

An open relay is a mail server that accepts mail from any client for any recipient and forwards it. RFC 821 allowed relaying by design. RFC 2505 (1999) said MTAs must be able to refuse unauthorized relaying, and RFC 5321 says a server declining to relay should return 550.

What is the difference between SPF, DKIM and DMARC?

SPF authorizes IP addresses to send with a domain in the envelope sender. DKIM signs message content with a domain's key. DMARC requires one of them to pass for a domain aligned with the visible From address, and tells receivers what to do with failures and where to send reports.

What is RFC 9989?

RFC 9989, published in May 2026, is the Standards Track version of DMARC. It obsoletes RFC 7489 and RFC 9091, replaces the Public Suffix List with a DNS Tree Walk, adds the np, psd and t tags and removes pct, rf and ri. Reporting is in RFC 9990 and RFC 9991.

What is STARTTLS stripping?

STARTTLS stripping is a man-in-the-middle attack where the server's plaintext offer of TLS is removed or the upgrade is blocked, so the sending server delivers in plaintext. RFC 3207 described it in 2002. MTA-STS and DANE let receiving domains tell senders to refuse delivery without valid TLS.

Should I use MTA-STS or DANE?

Use MTA-STS if your zone is not DNSSEC signed or your mail is hosted by a provider that supports it. Use DANE if you control a signed zone for your MX hosts. Many domains publish both, and TLS-RPT reports failures for either.

What was SMTP smuggling?

SMTP smuggling, published in December 2023, abused disagreement between two mail services about where a message ends. One service forwarded a non-standard end of data sequence and the next accepted it, so hidden SMTP commands created a second, spoofed message that could pass SPF based DMARC checks.

Is Postfix still vulnerable to SMTP smuggling?

Postfix 3.8.5, 3.7.10, 3.6.14, 3.5.24 and later include the long term fix, enabled by setting smtpd_forbid_bare_newline = normalize. Postfix 3.9 enables smtpd_forbid_unauth_pipelining by default. Check your distribution's package for backports and your main.cf settings.

What are the Gmail and Yahoo bulk sender requirements?

Since February 2024, bulk senders to Gmail (over 5,000 messages a day) and Yahoo must use SPF and DKIM, publish DMARC (at least p=none), align the From domain, keep spam rates below 0.3% and support one-click unsubscribe. Gmail also requires TLS and valid reverse DNS.

What does ARC do for DMARC?

ARC (RFC 8617) lets mailing lists and forwarders record and seal the authentication results they saw before modifying a message. A receiver that trusts that intermediary can use those results to accept a message whose DKIM or SPF broke in transit.

Does BIMI improve email security?

Not directly. BIMI displays a logo next to authenticated mail at supporting providers, and it requires DMARC at quarantine or reject. The security gain comes from that enforcement; BIMI does not change delivery.

Where Safeguard fits

Safeguard does not audit DNS records, test MTA configuration, filter mail or check DMARC alignment. Those jobs belong to your mail team, DNS tooling and mailbox provider. The honest overlap is the software. Postfix, Exim, Sendmail and OpenSMTPD are open source components that end up inside container images, appliance builds and application stacks, often far from the MX that gets patched. Safeguard can scan repositories, container images and SBOM files (safeguard scan --dir ., --image <name>, --sbom <file>), match the components it finds against vulnerability databases, and show which projects contain a given component and version, so a question like "which of our images still ship a Postfix older than 3.8.5" has an answer. Policies and gates can then stop an image with a known vulnerable MTA from shipping. It will not tell you whether a running server has smtpd_forbid_bare_newline set; that is a configuration check you run with postconf.

Mail servers and the libraries around them, such as TLS stacks, SPF and DKIM libraries and DNS resolvers, ship as open source packages inside the images you build, so the same advisory can sit unpatched in a dozen places besides your MX. The remediation flow below applies to those packaged components and the application dependencies next to them, not to DNS records or a hosted provider's servers.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

These demos show dependency, SBOM and coding assistant workflows, not mail server configuration or DNS auditing. You can download Safeguard and follow the CLI docs to try them on your own projects.

This demo is a real CLI session: install, open the interactive terminal with safeguard, ask it to fix a lodash CVE, and watch it read the finding and advisory, ask before each command, edit package.json to lodash 4.17.21, run npm install and npm test with approval, print a summary and push nothing. The same approval flow fits a repository whose Dockerfile pins a Postfix or Exim package that an advisory has just superseded.

Click through it at your own pace, or open it full screen.

This demo sets up the Safeguard runner on your own machine, approves it with its device code and then scans from the terminal. If your mail relay or alerting images are built on an internal build host, the local runner can scan those images and their SBOMs where they are built.

Click through it at your own pace, or open it full screen.

This demo connects Claude to the Safeguard MCP server with OAuth and shows how you choose which tools Claude can use. Once connected, you can ask which of your projects carry a given component and version, for example an Exim or Postfix build named in a new advisory, and get answers from your own Safeguard data.

Click through it at your own pace, or open it full screen.

Quick check

Your domain has SPF and DKIM set up but no DMARC record. Is a phishing email using your domain in the visible From address likely to be blocked?

Usually not. SPF and DKIM can both pass for the attacker's own domain while your domain sits in the header From. Without a DMARC record, nothing ties those results to the visible From or tells receivers to reject failures. Publish DMARC, read the reports and move toward enforcement.

You patched your inbound Postfix MX for SMTP smuggling. Why might you still need to patch an outbound relay?

SMTP smuggling needs a service that forwards a non-standard end of data sequence and a service that accepts it. Your outbound relay or smart host can play the forwarding role toward other domains, so it needs strict line ending handling too. Patch every hop you operate.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.