Introduction

A finance team receives an invoice approval email that appears to come from ceo@example.com. The display name is correct. The visible From domain is correct. The message does not need malware, a stolen mailbox, or a compromised SaaS account to work.

The attacker only needs a receiving mail system that cannot confidently reject the message.

That is where SPF, DKIM, and DMARC gaps matter. SPF says which servers may send for a domain. DKIM signs message content with a domain-owned key. DMARC connects those checks to the visible From domain and tells receivers what to do when authentication fails.

When any part is missing, weak, misaligned, or stuck at monitoring mode, your domain can be used as credible phishing infrastructure.

How email spoofing via SPF, DKIM, and DMARC gaps works at the protocol level

Email authentication is not one control. It is three controls that cover different parts of the message path.

SPF validates whether the connecting SMTP server is authorized for the envelope sender domain. DKIM validates whether a domain signed selected message headers and body content. DMARC checks whether SPF or DKIM passed and aligned with the visible From domain.

That alignment step is the part many teams miss. A message can have valid SPF or valid DKIM and still fail DMARC if the authenticated domain does not align with the visible From domain.

What each email authentication control validates.
Control What it validates What it does not prove
SPF The connecting SMTP server is authorized for the envelope sender domain The visible From header is trustworthy
DKIM A domain signed selected headers and body content with a private key The visible From domain is the same as the signing domain
DMARC SPF or DKIM passed and aligned with the visible From domain The message is harmless or wanted

SPF explained

SPF is published as a DNS TXT record. During evaluation, the receiver checks the sending IP against mechanisms in the SPF record.

A basic SPF record looks like this:

```dns example.com. TXT "v=spf1 include:_spf.google.com -all" ```

That record says Google’s SPF-authorized mail infrastructure may send for this domain, and everything else should fail.

The important ending is -all. A record ending in ~all is a softfail. A record ending in +all is effectively permissive and should be treated as dangerous.

SPF evaluation has a limit of 10 DNS-querying mechanisms and modifiers. include, a, mx, ptr, exists, and redirect count toward this limit; ip4 and ip6 do not. If the record exceeds the limit, receivers can return a permanent error.

DKIM explained

DKIM works differently from SPF. The sending system signs selected message headers and body content with a private key. The receiver uses the selector and signing domain in the DKIM-Signature header to fetch the public key from DNS and verify the signature.

A DKIM public key record usually looks like this:

```dns selector1._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..." ```

The selector matters because it lets a domain operate and rotate multiple keys. That is useful, but it also creates a common cleanup problem: old vendor selectors can stay published long after the vendor relationship ends.

DMARC explained

DMARC is the enforcement layer. It publishes a policy at _dmarc.example.com and checks whether SPF or DKIM produced an aligned pass with the visible From domain.

A strong DMARC record looks like this:

```dns _dmarc.example.com. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-aggregate@example.com; adkim=s; aspf=s" ```

DMARC passes only when at least one underlying mechanism passes for an aligned identifier. If neither SPF nor DKIM passes with alignment, the receiver applies the domain owner’s DMARC policy.

What the vulnerable configuration looks like

The most dangerous email spoofing configurations are not always blank records. Many look partly configured, which is why they survive for years.

A missing SPF record gives receivers no domain-published list of authorized senders:

```bash dig +short TXT example.com ```

Weak output:

```text (no v=spf1 record returned) ```

A permissive SPF record is worse because it explicitly allows broad sending:

```dns example.com. TXT "v=spf1 +all" ```

A softfail-only SPF record is common during migrations:

```dns example.com. TXT "v=spf1 include:_spf.google.com ~all" ```

Softfail is useful during rollout, but it should not become permanent without a clear reason.

  • Missing SPF — Receivers have no domain-published sender authorization list.

  • Permissive SPF — A record such as v=spf1 +all authorizes any sender and weakens spoofing resistance.

  • Softfail forever — A record ending in ~all often reflects an unfinished rollout rather than a final policy.

  • Too many SPF includes — Complex SPF records can exceed the 10 DNS lookup limit and return permanent errors during evaluation.

  • Old vendors still included — Former platforms may remain authorized to send mail for the domain.

Common DKIM gaps

A missing DKIM selector looks like this:

```bash dig +short TXT selector1._domainkey.example.com ```

Weak output:

```text (no DKIM key returned) ```

A stale selector is also risky. If old third-party mailers still have DNS keys under your domain, they may keep signing mail after the business relationship ends.

Weak operational patterns usually look like this:

```text selector: oldvendor domain: oldvendor._domainkey.example.com status: still published owner: unknown last used: unknown ```

  • No DKIM signing — SPF becomes the only path to DMARC pass, which is fragile across forwarding and third-party mail flows.

  • Non-aligned DKIM — A vendor may sign with its own domain, causing DKIM to pass but DMARC to fail for your visible From domain.

  • Unknown selectors — Old selectors can remain published after vendor offboarding.

  • Weak key management — Poor key rotation and unclear ownership make DKIM harder to trust during incidents.

Common DMARC gaps

No DMARC record means receivers do not get a domain-published policy:

```bash dig +short TXT _dmarc.example.com ```

Weak output:

```text (no DMARC record returned) ```

Monitoring-only DMARC looks like this:

```dns _dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com" ```

The p=none policy is useful for rollout, but it does not ask receivers to quarantine or reject spoofed mail.

A weak subdomain policy is another common gap:

```dns _dmarc.example.com. TXT "v=DMARC1; p=reject; sp=none; rua=mailto:dmarc@example.com" ```

That protects the organizational domain but leaves subdomains in monitoring mode. Attackers often prefer forgotten subdomains because they look believable and are less watched.

  • No DMARC record — Receivers do not get policy guidance for spoofed mail using your visible From domain.

  • p=none forever — The domain is monitored, but failing mail is not requested to be quarantined or rejected.

  • No aggregate reporting — Without rua reporting, teams lose visibility into who is sending as the domain.

  • Weak subdomain policy — The root domain may be protected while subdomains remain easier to abuse.

  • Partial enforcement — A low pct value can leave most unauthenticated mail outside enforcement.

How an attacker exploits this step by step

This is the defensive workflow an attacker is trying to profit from. Do not use it against domains you do not own or administer.

The attacker starts by checking public DNS for SPF, DKIM clues, and DMARC policy:

```bash dig +short TXT example.com dig +short TXT _dmarc.example.com dig +short TXT selector1._domainkey.example.com ```

They are looking for missing DMARC, p=none, weak SPF endings, multiple SPF records, excessive SPF includes, and old DKIM selectors.

The visible From domain is what the user sees. If DMARC is missing or not enforced, the attacker can attempt messages that display a trusted domain even though the message originated elsewhere.

Email spoofing is attractive because the attacker does not need to compromise Microsoft 365, Google Workspace, or the company’s CRM. The attacker can use separate infrastructure and rely on the receiving system’s inability or unwillingness to reject unauthenticated mail.

This is why SPF-only deployments are weak. SPF checks the envelope sender path, while users usually see the header From value. DMARC is what connects authentication back to the visible From domain.

Common spoofed identities and likely consequences.
Spoofed identity Likely consequence
Finance leader Fraudulent wire approval
IT helpdesk Credential theft
HR or payroll Payroll diversion
Security team Fake incident workflow or malicious link
Vendor billing Invoice redirection
SaaS support Account takeover workflow

How to detect it in your environment

Start with DNS. Then verify actual mail flow.

Check SPF with:

```bash dig +short TXT example.com | grep 'v=spf1' ```

Healthy output should show exactly one SPF record:

```text "v=spf1 include:_spf.google.com -all" ```

Check DMARC with:

```bash dig +short TXT _dmarc.example.com ```

Weak output:

```text "v=DMARC1; p=none; rua=mailto:dmarc@example.com" ```

Stronger output:

```text "v=DMARC1; p=reject; rua=mailto:dmarc-aggregate@example.com; adkim=s; aspf=s; pct=100" ```

For DKIM, start with selectors from your mail providers and recent message headers:

```bash dig +short TXT google._domainkey.example.com dig +short TXT selector1._domainkey.example.com dig +short TXT selector2._domainkey.example.com ```

Email authentication findings to flag during detection.
Finding Why it matters
No SPF record Receivers have no domain-published sender authorization list.
More than one SPF record SPF evaluation can produce permanent errors.
+all Any sender is authorized.
?all Unauthorized senders evaluate as neutral.
Long include chain SPF may exceed the 10 DNS lookup limit.
No DMARC record Receivers do not get domain policy.
p=none after rollout Spoofed mail is monitored, not blocked by requested policy.
No rua tag You lose aggregate visibility into who sends as your domain.
Unknown DKIM selectors Old vendors may still sign mail as your domain.
DKIM signing domain does not align DKIM can pass while DMARC still fails.

Review authentication headers on real messages

Send a test message from each authorized platform to a mailbox you control, then inspect headers.

A healthy result looks like this:

```text Authentication-Results: spf=pass smtp.mailfrom=example.com; dkim=pass header.d=example.com; dmarc=pass header.from=example.com ```

Weak or broken alignment looks like this:

```text Authentication-Results: spf=pass smtp.mailfrom=mailer.vendor.net; dkim=pass header.d=mailer.vendor.net; dmarc=fail header.from=example.com ```

That second result means the vendor authenticated itself, not your visible From domain.

How ExternalSight helps monitor email authentication drift

Email authentication records are part of your external attack surface. They change when marketing adds a sender, sales adds a sequencing tool, support changes a helpdesk platform, or IT migrates mail routing.

ExternalSight includes DNS scanning and an email spoofing scanner under the spoofing result key. Email security is also part of the scoring model, and findings can be classified with remediation planning.

ExternalSight supports continuous monitoring for verified domains, historical comparison, alerts, PDF export, and JSON export on supported plans. That makes it useful for detecting drift such as DMARC moving back to monitor-only, SPF becoming too broad, or email authentication findings reappearing after a vendor change.

ExternalSight should not be treated as a replacement for mail gateway controls, phishing defense, SIEM monitoring, or incident response. Its role here is external posture visibility and change detection.

Remediation — exact fix with config examples

Do not jump straight to p=reject if you do not know every legitimate sender. Fix sender inventory first, then enforce.

Create a sender inventory before editing DNS. Track the sender, purpose, From domain, SPF requirement, DKIM alignment status, and business owner.

A simple inventory should answer these questions: who sends mail for this domain, which platform sends it, which From domain is used, whether DKIM aligns, whether SPF is needed, and who owns the sender.

Example sender inventory before DMARC enforcement.
Sender Purpose Domain used in From SPF needed DKIM aligned Owner
Google Workspace Employee mail example.com Yes Yes IT
SendGrid Product email notifications.example.com Yes Yes Engineering
HubSpot Marketing marketing.example.com Yes Yes Marketing
Zendesk Support support.example.com Yes Yes Support

Fix SPF

Before:

```dns example.com. TXT "v=spf1 include:_spf.google.com include:sendgrid.net include:mailgun.org include:spf.protection.outlook.com include:servers.mcsv.net ~all" ```

Problems with this record include too many vendors on the root domain, possible SPF lookup-limit issues, a softfail ending, and unclear ownership across marketing, product, support, and employee mail.

After:

```dns example.com. TXT "v=spf1 include:_spf.google.com -all" ```

Move high-volume or vendor-specific mail to subdomains:

```dns notifications.example.com. TXT "v=spf1 include:sendgrid.net -all" marketing.example.com. TXT "v=spf1 include:servers.mcsv.net -all" support.example.com. TXT "v=spf1 include:mail.zendesk.com -all" ```

For domains that never send email, publish a deny-all SPF record:

```dns unused.example.com. TXT "v=spf1 -all" ```

Enable aligned DKIM for every sender

Before:

```text Vendor sends as: updates@example.com DKIM header.d: vendor-mailer.net DMARC: fails if SPF also lacks alignment ```

After:

```text Vendor sends as: updates@example.com DKIM header.d: example.com DMARC: can pass through aligned DKIM ```

Publish provider-specific DKIM records:

```dns selector1._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..." selector2._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..." ```

Use clear selector names so ownership is easy to understand:

```text google2026._domainkey.example.com sendgrid2026._domainkey.notifications.example.com hubspot2026._domainkey.marketing.example.com ```

When rotating keys, publish the new selector, update the sender, confirm passing DKIM, then remove the old selector after mail in transit has aged out.

Move DMARC from monitoring to enforcement

Start with monitoring only while you build visibility:

```dns _dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc-aggregate@example.com" ```

Move to quarantine when legitimate senders are aligned:

```dns _dmarc.example.com. TXT "v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-aggregate@example.com" ```

Increase rollout:

```dns _dmarc.example.com. TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc-aggregate@example.com" ```

Move to reject:

```dns _dmarc.example.com. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-aggregate@example.com; adkim=s; aspf=s; pct=100" ```

Set a subdomain policy so forgotten subdomains do not stay weak:

```dns _dmarc.example.com. TXT "v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc-aggregate@example.com" ```

If a subdomain has a special mail flow, give it its own DMARC record:

```dns _dmarc.marketing.example.com. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-marketing@example.com" ```

Protect domains that do not send mail

Parked domains, defensive domains, and brand domains should not be able to send mail.

Use deny-all SPF and reject-mode DMARC:

```dns example-brand.net. TXT "v=spf1 -all" _dmarc.example-brand.net. TXT "v=DMARC1; p=reject; rua=mailto:dmarc-aggregate@example.com" ```

Do not publish DKIM keys for non-sending domains.

Track every DNS change with an owner, ticket, and expiry review date.

Real-world incidents

In 2012, Wired reported that mathematician Zachary Harris discovered weak DKIM key practices after inspecting an unexpected Google recruiting email. The report described how a weak DKIM key could allow forged messages to appear authenticated, which made DKIM key length and rotation a practical operational issue rather than a theoretical control.

The same reporting also showed why third-party senders matter. Some weak DKIM keys were tied to vendors and old DNS records, not only to the primary corporate mail system. That is exactly the kind of gap that appears when teams onboard email platforms quickly but do not review selectors after the campaign, vendor, or integration ends.

Mailbox-provider requirements have also raised the baseline for bulk senders by requiring proper authentication and DMARC alignment. Keep sender compliance tied to current Google and Yahoo documentation when publishing operational policy, because mailbox-provider rules can change.

The practical lesson is simple: SPF, DKIM, and DMARC are not finished because DNS records exist. Key length, selector ownership, alignment, vendor delegation, reporting, and enforcement all matter.

Key takeaways

  • {'text': 'SPF authorizes sending infrastructure, but SPF alone does not prove the visible From domain is trustworthy.'}
  • {'text': 'DKIM proves a domain signed the message, but DMARC alignment decides whether that signature supports the visible From domain.'}
  • {'text': 'A p=none DMARC policy is useful for rollout, but it does not request blocking of unauthenticated spoofed mail.'}
  • {'text': 'SPF records can break when nested DNS lookups exceed the 10 DNS lookup limit.'}
  • {'text': 'Every third-party sender should have an owner, aligned DKIM, a narrow SPF scope, and a documented review date.'}
  • {'text': 'Non-sending domains should publish deny-all SPF and reject-mode DMARC.'}

Frequently asked questions

What is email spoofing via SPF, DKIM, and DMARC gaps?
It is abuse of weak email authentication records that lets an attacker send mail appearing to come from your domain. The attacker benefits when SPF is missing or too broad, DKIM is absent or not aligned, or DMARC is missing, monitoring-only, or not applied to subdomains.
Does DMARC pass if either SPF or DKIM passes?
Only if the passing mechanism is aligned with the visible From domain. A vendor can pass SPF or DKIM for its own domain while your message still fails DMARC because the authenticated domain does not align with your From domain.
Is p=none bad?
No. p=none is the right starting point when you are discovering legitimate senders. It becomes risky when it remains permanent after you have validated SPF, DKIM, and alignment.
Should every domain use p=reject?
Every domain should work toward reject-mode DMARC, but only after legitimate senders are aligned. For non-sending domains, p=reject with v=spf1 -all is usually the cleanest posture.
What is the SPF 10 lookup limit?
SPF evaluation allows up to 10 DNS-querying mechanisms and modifiers. include, a, mx, ptr, exists, and redirect count toward the limit. ip4 and ip6 do not. If the lookup limit is exceeded, SPF can return a permanent error.
How often should SPF, DKIM, and DMARC be reviewed?
Review them whenever a mail-sending vendor changes and on a recurring schedule. SaaS tools, marketing platforms, support systems, and transactional mail providers often introduce new senders faster than DNS owners expect.
Can ExternalSight detect email spoofing risk?
ExternalSight includes DNS scanning and an email spoofing scanner as part of its external attack surface monitoring workflow. It can help identify email authentication findings and monitor verified domains for posture drift, but it does not replace mail gateway enforcement or incident response.

Monitor email authentication as part of your external attack surface

ExternalSight helps teams scan internet-facing domains and monitor verified domains for external exposure changes. Its scan workflow includes DNS checks, email spoofing checks, issue classification, remediation planning, historical comparison, alerts, PDF export, JSON export on supported plans, and coverage-aware reporting.