SMTP has two layers, and they carry different sender addresses. Every authentication mechanism below depends on knowing which one it checks.
The envelope is the addressed sack the postal service reads; the message headers are the letterhead inside, which the sender writes freely. Nothing in SMTP prevents me typing any From address I like. That is not a bug being fixed — it is the protocol.
220 mx.google.com ESMTP ready EHLO mailer.acme.com 250-mx.google.com at your service 250-STARTTLS STARTTLS upgrade to TLS — opportunistic! MAIL FROM:<bounces@mailer.acme.com> envelope sender → SPF 250 2.1.0 OK RCPT TO:<jdoe@example.com> 250 2.1.5 OK DATA From: "Acme Billing" <billing@acme.com> header From → DMARC Subject: Invoice 4471 . 250 2.0.0 OK queued as 4A2F...
| Protocol | Job | Ports | Security relevance |
|---|---|---|---|
| SMTP | Server-to-server transport | 25 (MTA), 587 submission, 465 implicit TLS | Port 25 outbound from workstations should be blocked |
| IMAP | Client syncs with the server; mail stays | 143 / 993 | Legacy IMAP often bypasses MFA — a favourite for account takeover |
| POP3 | Client downloads and usually deletes | 110 / 995 | Attackers enable it to silently exfiltrate an entire mailbox |
# dig acme.com TXT
v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.10 ~all
| Mechanism | Meaning |
|---|---|
include: | Also accept whatever that domain's SPF authorises (recursive) |
ip4: / ip6: | Literal address or range |
mx: / a: | The domain's MX or A records may send |
-all | Hard fail — reject anything else |
~all | Soft fail — accept but mark |
?all | Neutral — effectively no policy |
SPF checks the envelope sender (Return-Path), not the From header the user sees. This is the crucial limitation: an attacker can pass SPF perfectly for their own domain while displaying billing@acme.com in From. SPF alone stops nothing that a user would notice.
permerror, which many receivers treat as a failure. Every new SaaS that sends on your behalf adds an include:. Audit this regularly and use flattening services carefully.The sending server signs selected headers and the body with a private key; the public key lives in DNS at <selector>._domainkey.<domain>. The receiver fetches it and verifies.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=acme.com; the signing domain — DMARC aligns on this s=selector1; which key to fetch h=from:to:subject:date; headers covered by the signature bh=...; b=... body hash; signature
Because the signature travels with the message, DKIM survives forwarding as long as nothing modifies the signed headers or body (mailing lists that append footers break it).
# dig _dmarc.acme.com TXT
v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; pct=100;
rua=mailto:dmarc@acme.com; ruf=mailto:forensic@acme.com
DMARC does two things SPF and DKIM cannot:
d=. Passing SPF for attacker.net no longer helps if From says acme.com.| Tag | Values | Meaning |
|---|---|---|
p= | none / quarantine / reject | Policy for your domain |
sp= | same | Policy for subdomains — set it, or subdomains are a gap |
adkim= / aspf= | r (relaxed) / s (strict) | Relaxed allows organisational-domain match, e.g. mail.acme.com |
pct= | 0–100 | Percentage of failing mail the policy applies to — the rollout dial |
rua= / ruf= | mailto | Aggregate (daily XML) and forensic reports |
p=none with rua=. Collect reports for a few weeks.p=quarantine with pct= ramping upward.p=reject; sp=reject, and publish reject on parked domains too — those are the ones attackers love.acrne.com, acme-invoices.net), display-name spoofing, compromised legitimate senders, or a Reply-To pointing somewhere else entirely. Those are the majority of real BEC attempts, which is why DMARC at reject is the floor rather than the answer.In Gmail: ⋮ → Show original gives the full source plus Google's own SPF/DKIM/DMARC verdicts. Read Received: headers bottom to top — the bottom one is the earliest hop, and everything below the first server you trust can be forged.
Return-Path: <bounce@mailer-xyz.top> envelope sender — mismatch is a flag Received: from mailer-xyz.top (198.51.100.9) by mx.google.com ... Tue, 12 Aug 2025 09:14:02 Authentication-Results: mx.google.com; spf=pass (google.com: domain of bounce@mailer-xyz.top designates 198.51.100.9 as permitted sender); dkim=pass header.d=mailer-xyz.top; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=acme.com From: "Acme Billing" <billing@acme.com> Reply-To: ap@acme-invoices.net the payload Message-ID: <...@mailer-xyz.top> X-Originating-IP: ...
Read that block properly and the story is complete: SPF and DKIM both pass — for the attacker's own domain — while DMARC fails because the visible From claims acme.com. The Reply-To sends any response to a domain the attacker controls. "SPF passed" in isolation means almost nothing.
header.from.A message shows spf=pass, dkim=pass, dmarc=fail, with From: finance@example.com. What happened?
p=reject this message should never have been delivered, so either the policy is still none, or it arrived at a receiver that ignores DMARC, or an internal relay is trusted and skipping the check.Note what none of these steps involve: an attachment, a malicious URL, or a signature to match. Content filtering has nothing to grab hold of. What does catch it is behaviour — this sender has never emailed this recipient, the reply-to differs from the from, the domain was registered eleven days ago, the tone and timing are anomalous, and finance is being asked to change payment details.
| SEG (gateway, MX-record) | API-integrated | |
|---|---|---|
| Position | In front of Google — MX points at it | Beside Google — OAuth into the tenant |
| Blocks pre-delivery | Yes | No — remediates seconds after delivery |
| Sees internal mail | No (never traverses it) | Yes — catches lateral phishing |
| Deployment risk | MX change; a failure stops mail | Very low; no mail-flow change |
| Signals available | The message itself | Message + full tenant history and behaviour |
The modern pattern — and the one Abnormal implements — is to let Google's native filtering handle the volume of commodity spam and malware, then layer an API-integrated behavioural product that reads the whole tenant to catch what content inspection structurally cannot: BEC, account takeover, vendor fraud and internal lateral phishing.
Layering question to answer explicitly: which system is authoritative for quarantine, and where do users report suspicious mail? Two quarantines with two release processes is a reliable source of both user frustration and missed detections.
The correlations that earn their keep: phish delivered → user clicked (proxy log) → login from new ASN (IdP) → inbox rule created (Workspace). Any one alone is ambiguous; together they are an incident, and building that chain is exactly what a SIEM is for.