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,psdandt, and removespct,rfandri. 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.
| Date | Event | What it meant for defenders | Source |
|---|---|---|---|
| August 1982 | RFC 821 defines SMTP | Servers relay mail between hosts; no sender authentication | RFC 821 |
| November 1988 | Internet worm spreads partly through sendmail's non-standard "debug" command | First large lesson that mail servers are internet facing attack surface | RFC 1135 (December 1989) |
| January 1999 | RFC 2487 defines STARTTLS for SMTP | Opportunistic encryption arrives, opt-in and downgradable | RFC 2487 |
| February 1999 | RFC 2505, BCP 30, anti-spam recommendations | MTAs MUST be able to refuse unauthorized relaying | RFC 2505 |
| February 2002 | RFC 3207 replaces RFC 2487 | Spells out that deleting "250 STARTTLS" is a man-in-the-middle attack | RFC 3207 |
| April 2006 | RFC 4408, SPF, published as Experimental | Domains can list IPs allowed to use them in the envelope sender | RFC 4408 |
| May 2007 | RFC 4871, DKIM, Standards Track; DomainKeys (RFC 4870) made Historic | Domains can sign messages with a key published in DNS | RFC 4871 |
| October 2008 | RFC 5321 replaces RFC 2821 | Declining to relay should return 550; bare LF dot LF MUST NOT end data | RFC 5321 |
| March 2011 | STARTTLS plaintext command injection published (CVE-2011-0411) | Commands sent before the TLS switch could be executed after it | Postfix write-up |
| September 2011 | RFC 6376, current DKIM | Clarified DKIM, including risks of the l= body length tag | RFC 6376 |
| April 2014 | RFC 7208, SPF on the Standards Track | Ten DNS lookup limit, permerror on excess | RFC 7208 |
| March 2015 | RFC 7489, DMARC, Informational | Policy and reporting tied to the visible From domain | RFC 7489 |
| October 2015 | RFC 7672, DANE for SMTP | DNSSEC signed TLSA records make TLS to an MX mandatory and authenticated | RFC 7672 |
| September 2016 | RFC 7960, DMARC and indirect mail flows | Documents why mailing lists and forwarders break under strict DMARC | RFC 7960 |
| October 2017 | CISA BOD 18-01 | US federal agencies must offer STARTTLS and reach DMARC p=reject within a year | CISA |
| January 2018 | RFC 8314 | Implicit TLS preferred for mail submission and access | RFC 8314 |
| February 2018 | Exim CVE-2018-6789, buffer overflow in base64 decoding | Memory safety in a decoder reachable from the network | Exim advisory |
| September 2018 | RFC 8461 (MTA-STS) and RFC 8460 (TLS-RPT) | HTTPS published policy against STARTTLS stripping, plus failure reports | RFC 8461, RFC 8460 |
| June 2019 | Exim CVE-2019-10149, versions 4.87 to 4.91 | Reported possible remote exploit; Exim 4.92 not affected | Exim advisory |
| July 2019 | RFC 8617, ARC, Experimental | Intermediaries can record and seal authentication results | RFC 8617 |
| September 2019 | Exim CVE-2019-15846, TLS SNI handling | Every Exim up to 4.92.1 accepting TLS was affected | Exim advisory |
| January and February 2020 | OpenSMTPD errata in OpenBSD 6.6 | An incorrect check and an out of bounds read let commands run as root | OpenBSD errata |
| September 2020 | M3AAWG Email Authentication Recommended Best Practices | Industry checklist for senders, intermediaries and receivers | M3AAWG |
| July 2021 | RFC 9091, PSD DMARC, Experimental | Public suffix operators can publish DMARC policy | RFC 9091 |
| 18 to 22 December 2023 | SMTP smuggling published; Postfix ships fixes on 22 December | Parsing differentials across two mail services enable spoofing that passes SPF | Postfix |
| 24 December 2023 | CVE-2023-51764 (Postfix), CVE-2023-51765 (Sendmail), CVE-2023-51766 (Exim) | Fixes and workarounds land across major MTAs | CERT/CC VU#302671 |
| 16 January 2024 | CERT/CC publishes VU#302671 | Coordinated note covering email services and appliances | CERT/CC |
| 21 January 2024 | Postfix 3.8.5, 3.7.10, 3.6.14, 3.5.24 | Normalize mode protects without rejecting bare LF | Postfix |
| 31 January 2024 | Sendmail 8.18.1 | Only CRLF accepted as line end; pipelining before replies refused | Sendmail release notes |
| 1 February 2024 | Gmail sender requirements take effect; Yahoo begins enforcement | Authentication, low spam rates and one-click unsubscribe become conditions of delivery | Google, Yahoo |
| May 2026 | RFC 9989, 9990, 9991 obsolete RFC 7489 | DMARC becomes Standards Track with a DNS Tree Walk | RFC 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 class | Attacker needs | What it breaks | Primary fix | Where the fix lives | Residual risk |
|---|---|---|---|---|---|
| Open relay abuse | Any internet connection | Your server's reputation and resources | Relay restrictions (RFC 2505) | MTA configuration | Compromised submission accounts relay just as well |
| Envelope sender spoofing | Any SMTP server | Bounce path and SPF identity | SPF (RFC 7208) | DNS TXT at the sending domain | Breaks on forwarding; does not protect the visible From |
| Content tampering and From spoofing | Any SMTP server | The message the user reads | DKIM (RFC 6376) plus DMARC (RFC 9989) | DNS and signing on outbound servers | Lookalike domains are untouched |
| Indirect flow breakage | Nothing; mailing lists do it by design | Legitimate mail under strict DMARC | ARC (RFC 8617), From rewriting at lists | Intermediary and receiver | ARC trust is receiver specific |
| STARTTLS stripping | A network position between servers | Confidentiality and integrity in transit | MTA-STS (RFC 8461) or DANE (RFC 7672) | DNS, HTTPS policy host, DNSSEC | First contact before a policy is cached |
| STARTTLS command injection | A network position | TLS session integrity | Discard buffered plaintext at the TLS switch | MTA code | Same class can recur in any STARTTLS protocol |
| SMTP smuggling | An account at one mail service | Message boundaries and SPF based DMARC | Strict end of data parsing | MTA code and settings at both ends | Any parser differential between hops |
| Memory and input bugs in MTAs | Network access to port 25 | The host itself | Patches from the project | Package and image updates | Unpatched 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:
- Port 25 accepts mail only for domains you host. Anything else gets a 5xx relay denied reply.
- 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.
- 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) andt(a replacement for somepctfunctionality). - Tags removed:
pct,rfandri. - 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=rejectwithout 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
| Layer | Year first published | What it authenticates | What it cannot do alone |
|---|---|---|---|
| SPF | 2006 (Standards Track 2014) | The connecting IP for the envelope sender or HELO domain | Protect the visible From; survive forwarding |
| DKIM | 2007 (current RFC 2011) | A domain's signature over headers and body | Say which domain the user should trust |
| DMARC | 2015 (Standards Track 2026) | Alignment of SPF or DKIM with the header From, plus policy | Stop 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.comwithv=STSv1and anidthat 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, containingversion: STSv1, amodeofenforce,testingornone, onemxline per allowed MX pattern, andmax_agein 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
| Question | MTA-STS | DANE |
|---|---|---|
| Trust anchor | Web PKI certificate on the policy host and on each MX | DNSSEC chain to your zone |
| Needs DNSSEC | No | Yes, on the MX host's zone |
| Extra infrastructure | An HTTPS host at mta-sts.<domain> | TLSA records kept in step with key changes |
| First contact protection | No, trust on first use with caching | Yes, if the sender validates DNSSEC |
| Main operational risk | Expired certificate on an MX, or policy left in testing forever | Key rollover without updating TLSA first |
| Works with hosted mailbox providers | Usually, through a CNAME to the provider | Only 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:
- Service A, where the attacker has an account, accepts a message containing a non-standard end of data sequence and forwards it verbatim.
- 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:
| Date | Postfix action |
|---|---|
| 18 December 2023 | Learns of the publication |
| 19 December 2023 | Researches and implements a fix |
| 21 December 2023 | Fixes problems found in validation with BDAT and XCLIENT |
| 22 December 2023 | Publishes Postfix 3.8.4, 3.7.9, 3.6.13 and 3.5.23 |
| 24 December 2023 | CVEs assigned for Postfix, Exim and Sendmail; distributions ship updates |
| 21 January 2024 | Publishes 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.
| Class | Example (project advisory) | Date | Affected | What the advisory says to do |
|---|---|---|---|---|
| Debug or test feature reachable remotely | Sendmail "debug" command used by the internet worm | November 1988 | Sendmail of the time | Remove the debug command (RFC 1135) |
| State confusion at a TLS transition | STARTTLS plaintext command injection, CVE-2011-0411 | March 2011 | Postfix and several other implementations | Discard plaintext buffered before the TLS switch; upgrade |
| Memory safety in a decoder | Exim CVE-2018-6789, buffer overflow in base64d() | February 2018 | Exim before the fix | Upgrade; no mitigation known at the time |
| Remotely reachable flaw with few details released | Exim CVE-2019-10149, reported as a possible remote exploit | June 2019 | Exim 4.87 to 4.91 | Upgrade; Exim 4.92 not affected |
| TLS handshake parsing | Exim CVE-2019-15846, SNI handling | September 2019 | All Exim up to 4.92.1 accepting TLS | Upgrade; disabling TLS listed as not recommended |
| Incorrect input check reaching mail delivery | OpenSMTPD, OpenBSD 6.6 errata 019 | 30 January 2020 | smtpd in OpenBSD 6.6 | Apply the source patch |
| Out of bounds read affecting the spool envelope | OpenSMTPD, OpenBSD 6.6 errata 021 | 24 February 2020 | smtpd in OpenBSD 6.6 | Apply the source patch |
| Protocol parsing differential | SMTP smuggling, CVE-2023-51764/51765/51766 | December 2023 | Postfix, Sendmail, Exim and hosted services | Upgrade 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 check | Location | Pass condition |
|---|---|---|
| MX | example.com MX | All hosts known and owned |
| SPF | example.com TXT | One record, 10 or fewer lookup terms, -all on non-sending domains |
| DKIM | selector._domainkey.example.com | Active selectors have keys; no l= on signatures |
| DMARC | _dmarc.example.com | Enforcement where safe; rua read; explicit records for subdomains |
| MTA-STS | _mta-sts TXT and policy file | enforce, all MX listed, long max_age |
| TLS-RPT | _smtp._tls TXT | Reports arrive and are read |
| DANE | _25._tcp.<mx> TLSA | Matches the live key; zone signed |
| STARTTLS | Each MX on port 25 | Valid certificate, TLS 1.2 or later |
| Relay | Each MX | 5xx for external recipients |
| MTA version | Each host and image | Patched 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
| Requirement | Gmail, all senders | Gmail, over 5,000 a day | Yahoo, all senders | Yahoo, bulk senders |
|---|---|---|---|---|
| SPF or DKIM | Required | Both required | Required | Both required |
| DMARC | Not required | Required, p=none allowed | Strongly urged | Required, at least p=none, must pass |
| From alignment | Not stated | Required for direct mail | Not stated | Required, relaxed acceptable |
| Forward and reverse DNS | Required | Required | Required | Required |
| TLS for transmission | Required | Required | Not stated on the page | Not stated on the page |
| Spam rate | Below 0.3% | Below 0.30% | Below 0.3% | Below 0.3% |
| One-click unsubscribe | Not stated | Required for marketing and subscribed mail | Not stated | Required; 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
testingfor years. Testing mode reports but does not protect. Read the TLS-RPT reports, fix failures, then switch toenforce. - 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 = rejecteverywhere without testing. Postfix warns it is more likely to reject legitimate mail.normalizewithmynetworksexcluded 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 situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull 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
- RFC 821: Simple Mail Transfer Protocol (August 1982)
- RFC 1135: The Helminthiasis of the Internet (December 1989)
- RFC 2487: SMTP Service Extension for Secure SMTP over TLS (January 1999)
- RFC 2505: Anti-Spam Recommendations for SMTP MTAs, BCP 30 (February 1999)
- RFC 3207: SMTP Service Extension for Secure SMTP over Transport Layer Security (February 2002)
- RFC 4408: Sender Policy Framework, Experimental (April 2006)
- RFC 4870: DomainKeys, Historic (May 2007)
- RFC 4871: DomainKeys Identified Mail Signatures (May 2007)
- RFC 5321: Simple Mail Transfer Protocol (October 2008)
- RFC 6376: DomainKeys Identified Mail (DKIM) Signatures (September 2011)
- RFC 7208: Sender Policy Framework (SPF) (April 2014)
- RFC 7489: DMARC, Informational (March 2015)
- RFC 7671: The DANE Protocol, Updates and Operational Guidance (October 2015)
- RFC 7672: SMTP Security via Opportunistic DANE TLS (October 2015)
- RFC 7960: Interoperability Issues between DMARC and Indirect Email Flows (September 2016)
- RFC 8314: Cleartext Considered Obsolete, Use of TLS for Email Submission and Access (January 2018)
- RFC 8460: SMTP TLS Reporting (September 2018)
- RFC 8461: SMTP MTA Strict Transport Security (MTA-STS) (September 2018)
- RFC 8617: The Authenticated Received Chain (ARC) Protocol (July 2019)
- RFC 9091: Experimental DMARC Extension for Public Suffix Domains (July 2021)
- RFC 9989: Domain-based Message Authentication, Reporting, and Conformance (DMARC) (May 2026)
- RFC 9990: DMARC Aggregate Reporting (May 2026)
- RFC 9991: DMARC Failure Reporting (May 2026)
- Postfix: SMTP Smuggling (Wietse Venema, last updated 22 January 2024)
- Postfix: Plaintext command injection in multiple implementations of STARTTLS, CVE-2011-0411
- CERT/CC: VU#302671, SMTP end-of-data uncertainty can be abused to spoof emails and bypass policies
- Sendmail: RELEASE_NOTES (8.18.1, 2024/01/31)
- Exim: security advisories index
- Exim: CVE-2019-10149
- Exim: CVE-2019-15846
- Exim: CVE-2018-6789
- Exim: ChangeLog (JH/12, end of DATA handling)
- OpenBSD 6.6 errata (smtpd fixes 019 and 021)
- CISA: BOD 18-01, Enhance Email and Web Security (16 October 2017)
- M3AAWG: Email Authentication Recommended Best Practices (September 2020)
- Google: Email sender guidelines
- Yahoo: Sender best practices
- BIMI Group: FAQs for senders and ESPs