What an enforced DMARC policy actually protects
You moved your domain to p=reject, aggregate reports are clean, and direct spoofing of your domain stopped. (A reject policy is a strong signal rather than a guaranteed bounce: RFC 9989 §7.4 says Mail Receivers MUST NOT reject a message solely because of p=reject, and absent other analysis SHOULD treat it as p=quarantine. Most still reject in practice, but the receiver decides.) Then a user forwards a phishing message that still appears to come from your brand. The policy is working exactly as specified. The attack you are now seeing is one DMARC was never designed to stop, which is display name spoofing and the related impersonation techniques below.
DMARC binds one thing: the domain in the visible From: header, the RFC5322.From identifier. The spec selects this domain because it is the field end users read to identify the source of a message. A message passes DMARC when at least one of SPF or DKIM produces a pass and that pass is aligned to the From domain. As RFC 9989 §5.3.5 puts it, "If one or more of the Authenticated Identifiers align with the Author Domain, the message is considered to pass the DMARC mechanism check." Identifier alignment itself is defined in RFC 9989 §3.2.10, with adkim and aspf defaulting to relaxed. Nothing in that mechanism inspects the friendly name, the reply address, or how closely a sending domain resembles yours.
The specification states this limit plainly: DMARC does not address the use of visually similar domain names ("cousin domains") or abuse of the RFC5322.From human-readable display-name. (Historically, this scope was set out in the Anti-Phishing section of RFC 7489 §2.4, the document DMARCbis obsoletes.) It does not protect against attacks that never use the protected domain in the From field. Once you know that boundary, you stop chasing a DMARC misconfiguration that does not exist and start deploying the control that helps.
Confirm DMARC is genuinely at enforcement first
Before treating this as a DMARC limitation, confirm the policy really is enforcing. A record stuck at p=none lets unauthenticated mail through and is a different problem. The same is true if the record carries a test-mode flag: t=y (RFC 9989 §4.7) asks receivers to apply the next-lower policy while still reporting, so a p=reject; t=y record behaves like quarantine in practice. (DMARCbis removed the old pct tag that RFC 7489 used for partial rollout. Records that still carry pct parse without error, because unknown tags are ignored, but it no longer changes how receivers act.)
dig TXT _dmarc.example.com +short
dig TXT _dmarc.example.com @1.1.1.1 +short
You want one record, policy at quarantine or reject:
"v=DMARC1; p=reject; rua=mailto:[email protected]"
If you see p=none, the spoofed mail using your exact domain is passing through because you are still in monitoring mode. That is a separate fix: read DMARC policy not enabled and moving from p=none to p=reject. Run the domain through the DMARCTrust DMARC checker for a quick read of the published policy. The rest of this guide assumes the policy is confirmed at enforcement.
Gap 1: display name spoofing
The most common post-enforcement complaint. An email address has two parts in the header: the display name and the address itself. Mail clients show the display name prominently and often hide the address. The attacker exploits that.
From: "Acme Billing" <[email protected]>
The From domain here is gmail.com, not acme.com. The message can pass DMARC for gmail.com, because it really was sent through Gmail by the attacker, and your p=reject on acme.com never enters the evaluation. To the recipient, the inbox row reads "Acme Billing." Your domain was never used, so your DMARC policy has nothing to act on.
What helps:
- Anti-impersonation rules at the receiving gateway. Microsoft Defender for Office 365, Google Workspace, and most secure email gateways can flag or quarantine inbound mail whose display name matches a protected name or executive while the From domain is external. This is an inbound control on the recipient's side, so it protects your own employees from impersonation of each other; it does not protect customers on other mail systems.
-
BIMI gives recipients a positive signal on mail that genuinely passes your DMARC, so a display-name forgery from
gmail.comshows no logo while your real mail does. BIMI requires DMARC atp=quarantineorp=rejectas a precondition (BIMI Group implementation guide). It raises the cost of a convincing forgery but does not block the forged message. - User reporting. A one-click report-phishing path turns recipients into a detection layer for the cases automation misses.
Gap 2: lookalike and cousin domains
Here the attacker registers a domain that reads like yours and sends from it. Because it is a real domain they control, they can publish full SPF, DKIM, and even p=reject, and pass DMARC on their own domain.
example.com <- your domain
exampIe.com <- capital I substituted for lowercase l (homoglyph)
example-support.com <- added word (cousin domain)
examp1e.com <- digit 1 for letter l
xn--exmple-... <- internationalized homoglyph (punycode)
DMARC evaluates only the literal From domain, so it treats exampIe.com as an unrelated third party. The specification calls this out directly: visually similar "cousin domains" are out of scope. (This scope statement dates to RFC 7489 §2.4 and carries forward into DMARCbis.) What helps:
- Lookalike and exact-domain monitoring. Watch new domain registrations and certificate transparency logs for homoglyph and cousin variants of your brand, so you learn about a malicious registration before a campaign launches rather than after.
-
Defensive registration. Register the closest and most dangerous variants yourself, point them at nothing, and publish a hard policy so they cannot be used to send. A parked lookalike you own should carry its own enforcing record:
You cannot register every permutation. Prioritize the handful a human would most plausibly misread._dmarc.exampIe.com. IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]" - Takedown process. When monitoring flags a variant you do not own, having a registrar and host abuse-contact path ready shortens the window the domain is live.
Gap 3: compromised legitimate accounts
If an attacker steals the credentials for a real mailbox on your domain, the mail they send is authentic. It is signed by your DKIM key, sent from an authorized IP in your SPF, and aligned to your From domain. SPF, DKIM, and DMARC all pass because the message genuinely originates from your domain.
Authentication-Results: mx.receiver.example;
spf=pass smtp.mailfrom=example.com;
dkim=pass header.d=example.com;
dmarc=pass header.from=example.com
DMARC cannot distinguish an authorized user from an attacker who holds that user's password. This is an account security problem, not an authentication one. What helps: enforce multi-factor authentication, monitor for anomalous send volume and unusual sending geography, and revoke sessions and rotate credentials the moment an account is suspected compromised.
Gap 4: reply-to abuse
DMARC does not evaluate the Reply-To: header at all. An attacker can send a message that passes DMARC for some throwaway or compromised domain, set a trusted display name, and route every reply to an address they control.
From: "Acme Payroll" <[email protected]>
Reply-To: [email protected]
The victim hits reply and the conversation goes straight to the attacker. Because the From domain authenticated correctly for its own domain, nothing in the DMARC chain objects. Gateway rules that flag a mismatch between From: and Reply-To: domains, plus user training on reply-address inspection, are the practical controls here.
How to read this in your reports
DMARC aggregate reports only ever describe mail that used your domain in the From field. Display-name spoofing, lookalike domains, and reply-to abuse will not appear there at all, because those attacks never touch your domain. A clean aggregate report is consistent with active impersonation of your brand. Use the DMARCTrust DMARC report view to confirm there is no residual unauthenticated mail on your own domain, then accept that the remaining impersonation lives outside DMARC's scope and needs the layered controls above.
To see exactly what a receiver computed for a suspicious message you do have a copy of, paste its raw headers into the email header analyzer. It surfaces the real From domain behind the display name and the authentication verdict, which tells you immediately whether the attack used your domain or merely your name.
A realistic control map
Match each attack to the control that addresses it. None is a single switch.
-
Direct domain spoofing (uses
example.comin From): DMARC atp=reject. This you have solved. - Display name spoofing (forged friendly name, attacker From): inbound gateway anti-impersonation rules, BIMI for positive signal, user reporting.
- Lookalike or cousin domains: registration and certificate-transparency monitoring, defensive registration with enforcing policy, takedown process.
- Compromised account: multi-factor authentication, anomaly detection, fast credential revocation.
- Reply-to abuse: From and Reply-To mismatch rules, recipient training.
Set the expectation honestly with stakeholders: reaching p=reject closes the largest and most automatable attack, exact-domain spoofing. It is the foundation the other layers build on, not the whole defense.
Related fixes
- If your policy is not actually enforcing yet, read moving from p=none to p=reject.
- If you want a verified logo on mail that does pass DMARC, read BIMI logo not displaying.
- If legitimate mail from a provider is failing DMARC, read ESP mail fails DMARC.
- If identifiers do not line up with the From domain, read DMARC alignment issues.
- Check any domain's published policy with the DMARCTrust DMARC checker.