What You'll Learn
- Explain the purpose and mechanism of SPF (Sender Policy Framework) and interpret SPF DNS TXT records
- Describe how DKIM (DomainKeys Identified Mail) uses cryptographic signing to verify email integrity and sender authenticity
- Explain how DMARC (Domain-based Message Authentication) enforces policy alignment between SPF/DKIM and the From domain
- Read and interpret Authentication-Results headers to determine SPF, DKIM, and DMARC pass/fail status
- Identify the specific techniques attackers use to bypass each authentication mechanism
- Articulate why all three protocols are required together and why any single one is insufficient
The Problem All Three Protocols Solve
SMTP — the protocol that delivers email — was designed in 1982. It has no built-in sender verification. Any server on the internet can connect to your mail server and claim to be ceo@yourcompany.com. SMTP will accept it without question. This is not a bug — it is the original design. Email was built for a trusted academic network, not for a global system full of adversaries.
SPF, DKIM, and DMARC are three protocols layered on top of SMTP to retroactively add sender verification. Each solves a different piece of the authentication puzzle:
| Protocol | Question It Answers | How It Works |
|---|---|---|
| SPF | Is this server allowed to send email for this domain? | DNS lookup of authorized sender IPs |
| DKIM | Was this message tampered with in transit? | Cryptographic signature verified against DNS public key |
| DMARC | Does the From domain align with SPF/DKIM results? | Policy enforcement + alignment check |
Think of it this way: SPF checks the mailman's ID badge. DKIM checks that the letter was not opened and resealed. DMARC checks that the return address on the letter matches the ID badge. All three checks must pass for full confidence.
SPF: Sender Policy Framework
SPF lets a domain owner publish a list of IP addresses and servers authorized to send email on behalf of that domain. When a receiving server gets an email claiming to be from example.com, it performs a DNS TXT lookup on example.com and checks whether the sending server's IP is on the authorized list.
SPF Record Syntax
SPF records are published as DNS TXT records on the domain:
v=spf1 ip4:203.0.113.0/24 include:_spf.google.com include:sendgrid.net -all
| Mechanism | Meaning |
|---|---|
v=spf1 | SPF version 1 (required prefix) |
ip4:203.0.113.0/24 | Allow any IP in this /24 range |
include:_spf.google.com | Also allow any IP authorized by Google's SPF record |
include:sendgrid.net | Also allow SendGrid's mail servers |
-all | Hard fail — reject anything not explicitly authorized |
SPF Qualifiers
The qualifier before all determines what happens to unauthorized senders:
| Qualifier | Syntax | Result | Meaning |
|---|---|---|---|
| Pass | +all (or just all) | pass | Anyone can send — useless, defeats the purpose |
| Hard Fail | -all | fail | Unauthorized senders should be rejected |
| Soft Fail | ~all | softfail | Unauthorized senders are suspicious but not rejected |
| Neutral | ?all | neutral | No assertion — SPF provides no information |
Most organizations use ~all (soft fail) instead of -all (hard fail). Why? Because hard fail can break legitimate email from third-party services that were not added to the SPF record. The practical effect: most phishing emails that fail SPF get a "softfail" result, which many mail servers treat as "deliver anyway but mark as suspicious." This is why SPF alone is not enough.
How to Check SPF
You can query any domain's SPF record from the command line:
dig TXT example.com +short | grep spf
nslookup -type=TXT example.com
In email headers, SPF results appear in the Authentication-Results header:
Authentication-Results: mx.company.com;
spf=pass (sender IP is 209.85.220.41) smtp.mailfrom=user@example.com
Authentication-Results: mx.company.com;
spf=softfail (sender IP is 45.33.18.201) smtp.mailfrom=x92@mass-mailer.info
SPF Limitations
| Limitation | Explanation |
|---|---|
| Checks envelope sender only | SPF validates MAIL FROM (Return-Path), NOT the From header the user sees |
| Breaks on forwarding | When email is forwarded, the forwarding server's IP is not in the original domain's SPF record |
| 10 DNS lookup limit | Complex SPF records with many include statements can exceed the limit, causing permerror |
| Does not verify content | SPF confirms the server is authorized — it says nothing about whether the message was modified |
DKIM: DomainKeys Identified Mail
DKIM adds a cryptographic signature to outgoing emails. The sending server signs specific headers and the body using a private key. The corresponding public key is published in DNS. Receiving servers retrieve the public key and verify the signature — confirming that the email was not modified after signing and that the signing domain authorized the message.
How DKIM Works
- Sending server generates a hash of specified headers + body
- Signs the hash with the domain's private key
- Adds
DKIM-Signatureheader to the email - Receiving server extracts the
d=(domain) ands=(selector) from the DKIM-Signature header - Queries DNS for
selector._domainkey.domain.comto retrieve the public key - Verifies the signature against the hash of the received message
DKIM-Signature Header
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=selector1;
h=from:to:subject:date:message-id;
bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;
b=dGhpcyBpcyBhIGZha2Ugc2lnbmF0dXJlIGZvciBkZW1vbnN0cmF0aW9u...
| Tag | Meaning |
|---|---|
v=1 | DKIM version |
a=rsa-sha256 | Signing algorithm |
c=relaxed/relaxed | Canonicalization (how whitespace is handled) |
d=example.com | Signing domain — this is the domain taking responsibility |
s=selector1 | Selector — identifies which DNS key record to use |
h=from:to:subject... | Which headers were included in the signature |
bh=... | Body hash |
b=... | The signature itself |
Verifying DKIM via DNS
dig TXT selector1._domainkey.example.com +short
Returns something like:
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQE..."
In headers, DKIM results appear as:
Authentication-Results: mx.company.com;
dkim=pass header.d=example.com header.s=selector1
DKIM Limitations
| Limitation | Explanation |
|---|---|
| Does not verify the sender IP | DKIM confirms the message was signed by the domain — not that the sending server was authorized |
| Survives forwarding | Unlike SPF, DKIM signatures typically survive forwarding (advantage) |
| Signature covers specific headers only | Headers not listed in h= can be modified without breaking the signature |
| Key management burden | Organizations must generate, publish, and rotate DKIM keys |
| Replay attacks | A legitimately signed email can be resent by an attacker — the signature is still valid |
DKIM replay attacks are increasingly common. An attacker signs up for a legitimate trial account at a SaaS company, triggers a confirmation email, then replays that signed email to thousands of targets. The DKIM signature is valid because the email was genuinely signed by the SaaS company. This is why DKIM alone is not sufficient.
DMARC: Domain-based Message Authentication, Reporting & Conformance
DMARC builds on SPF and DKIM by adding two critical features: alignment and policy enforcement.
The Alignment Problem
SPF validates the envelope sender (MAIL FROM). DKIM validates the signing domain (d= tag). But neither one directly validates the From header that the user actually sees. An attacker can:
- Set
MAIL FROMtoattacker@evil.com(SPF passes for evil.com) - Sign the email with DKIM for
evil.com(DKIM passes for evil.com) - Set
From: ceo@yourcompany.com(what the user sees)
SPF passes. DKIM passes. The user sees a spoofed From address. DMARC closes this gap.
How DMARC Works
DMARC requires that either SPF or DKIM not only passes, but also aligns with the domain in the From header:
- SPF alignment: The domain in
MAIL FROMmust match (or be a subdomain of) theFromheader domain - DKIM alignment: The
d=domain in the DKIM signature must match (or be a subdomain of) theFromheader domain
If neither SPF nor DKIM is both passing AND aligned with the From domain, DMARC fails.
DMARC Record Syntax
Published as a DNS TXT record at _dmarc.domain.com:
v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com; pct=100; adkim=s; aspf=s
| Tag | Meaning |
|---|---|
v=DMARC1 | DMARC version |
p=reject | Policy: reject emails that fail DMARC |
p=quarantine | Policy: send failures to spam |
p=none | Policy: do nothing (monitoring only) |
rua=mailto:... | Where to send aggregate reports |
ruf=mailto:... | Where to send forensic (failure) reports |
pct=100 | Apply policy to 100% of failing emails |
adkim=s | DKIM alignment: strict (exact domain match) |
aspf=s | SPF alignment: strict (exact domain match) |
Over 70% of domains still use p=none for DMARC. This means they are monitoring DMARC failures but not enforcing any policy — spoofed emails are delivered normally. As a SOC analyst, when you see DMARC fail with p=none, the email was still delivered. The authentication result is "fail" but the policy action is "none." You must still investigate.
Checking DMARC via DNS
dig TXT _dmarc.example.com +short
DMARC in Authentication-Results Headers
Authentication-Results: mx.company.com;
spf=pass (sender IP is 209.85.220.41) smtp.mailfrom=user@example.com;
dkim=pass header.d=example.com header.s=selector1;
dmarc=pass (p=REJECT) header.from=example.com
Authentication-Results: mx.company.com;
spf=softfail smtp.mailfrom=bulk-mailer.info;
dkim=none;
dmarc=fail (p=NONE) header.from=microsoft.com
The second example shows a phishing email: SPF softfails (sent from unauthorized server), no DKIM signature, and DMARC fails — but the policy is p=NONE, so the email was delivered anyway.
Reading Authentication-Results: The SOC Analyst's Shortcut
The Authentication-Results header is the single most important header for phishing triage after your initial Return-Path/Received chain analysis. It gives you the combined verdict of all three protocols in one place.
Quick Reference
| Result | Meaning | Action |
|---|---|---|
spf=pass, dkim=pass, dmarc=pass | Fully authenticated | Likely legitimate (still check content) |
spf=pass, dkim=pass, dmarc=fail | Auth passed but alignment failed | Likely spoofed — From domain does not match authenticated domain |
spf=fail, dkim=none, dmarc=fail | No authentication passed | High-confidence phishing indicator |
spf=softfail, dkim=pass, dmarc=pass | DKIM saved it | SPF misconfiguration but DKIM alignment confirmed — likely legitimate |
spf=pass, dkim=fail, dmarc=pass | SPF saved it | Message modified in transit (DKIM broke) but SPF aligned — investigate modification |
dmarc=fail (p=NONE) | DMARC failed but no enforcement | Email delivered despite failure — requires manual investigation |
Your triage shortcut: Look at DMARC first. If dmarc=pass, the email passed either SPF or DKIM with proper alignment — the authentication layer is satisfied (though the email could still be malicious content from a legitimate domain). If dmarc=fail, check the policy: p=reject means it should have been blocked (if delivered, check your gateway); p=none means it was delivered despite failing — investigate manually.
How Attackers Bypass Each Protocol
Understanding the bypass techniques helps you recognize sophisticated phishing that passes basic authentication checks.
SPF Bypasses
| Technique | How It Works |
|---|---|
| Shared hosting exploitation | Attacker sends from a server whose IP is in the target's SPF record (e.g., shared cloud IP ranges) |
| Subdomain abuse | Target has SPF on company.com but not on mail.company.com — attacker spoofs the subdomain |
| Include chain abuse | Overly broad include statements (e.g., include:amazonses.com) authorize thousands of unrelated senders |
DKIM Bypasses
| Technique | How It Works |
|---|---|
| Replay attack | Legitimately signed email is re-sent to new targets — signature remains valid |
| Key theft | Compromised mail server yields the private DKIM key — attacker signs arbitrary messages |
| Selector enumeration | Attacker finds and exploits weak or test selectors left in DNS |
DMARC Bypasses
| Technique | How It Works |
|---|---|
p=none exploitation | Most domains do not enforce DMARC — attacker spoofs freely |
| Subdomain policy gap | DMARC set on company.com but sp=none allows subdomain spoofing |
| Look-alike domains | conpany.com instead of company.com — DMARC passes for the attacker's domain |
| Compromised third-party | Attacker compromises a SaaS tool authorized in SPF/DKIM — sends from legitimate infrastructure |
Look-alike domains are DMARC's blind spot. DMARC validates that the email is authentically from the domain in the From header. If the From header says support@micros0ft.com (with a zero), DMARC validates against micros0ft.com — which the attacker controls. SPF passes, DKIM passes, DMARC passes. The email is "authenticated" but still phishing. This is why header analysis (Lesson PH-1) and content analysis must complement authentication checks.
Why All Three Are Needed
| If You Only Have... | What Can Still Be Spoofed |
|---|---|
| SPF only | From header (SPF checks MAIL FROM, not From); message content can be modified |
| DKIM only | Sender IP not verified; replay attacks possible; From header not aligned |
| SPF + DKIM (no DMARC) | From header can differ from both MAIL FROM and DKIM d= domain — no alignment enforcement |
| SPF + DKIM + DMARC | From header must align with at least one authenticated identifier — comprehensive protection |
Even with all three, remember: authentication confirms the email came from the claimed domain's authorized infrastructure. It does not confirm the email is safe. A compromised legitimate account sends fully authenticated phishing. Content analysis remains essential.
Key Takeaways
- SPF validates the sending server's IP against a domain's published authorized sender list — but checks the envelope sender, not the visible From header
- DKIM cryptographically signs email headers and body, ensuring integrity — but does not verify the sender IP and is vulnerable to replay attacks
- DMARC enforces alignment between SPF/DKIM results and the From domain — closing the gap that lets attackers pass SPF/DKIM while spoofing the From header
- The
Authentication-Resultsheader is your one-stop shop for SPF, DKIM, and DMARC verdicts during triage - Most domains use
p=nonefor DMARC — meaning failed emails are still delivered, and you must investigate them manually - All three protocols together provide strong authentication, but look-alike domains and compromised accounts can still pass all checks
- Authentication tells you where the email came from — content analysis tells you whether it is malicious
What's Next
You now understand the infrastructure that proves (or disproves) an email's claimed origin. In the next lesson, we shift from the technical envelope to the human target. You will learn to classify phishing by type — credential harvesters, malware delivery, BEC, spear phishing — and analyze the URL and social engineering tactics attackers use to manipulate recipients into clicking, downloading, or transferring funds. These classification skills are what you will apply in Lab 4.3 when you triage a mix of real-world phishing samples.
Knowledge Check: SPF, DKIM & DMARC Authentication
10 questions · 70% to pass
What specific question does SPF answer about an incoming email?
An SPF record reads: v=spf1 ip4:203.0.113.0/24 include:_spf.google.com ~all. What does the ~all qualifier mean?
In a DKIM-Signature header, what does the d= tag represent, and why is it critical for DMARC alignment?
An email's Authentication-Results header shows: spf=pass, dkim=pass, dmarc=fail. How is this possible?
In Lab 4.2, you check the DMARC record for a domain and find: v=DMARC1; p=none; rua=mailto:reports@example.com. What does p=none mean for your phishing investigation?
An attacker registers the domain micros0ft.com (with a zero) and sets up proper SPF, DKIM, and DMARC records. They send phishing emails with From: support@micros0ft.com. What will the authentication results show?
Why does SPF frequently break when emails are forwarded, but DKIM typically survives forwarding?
In Lab 4.2, you analyze an email with Authentication-Results showing: spf=softfail, dkim=none, dmarc=fail (p=NONE). The email claims to be from your company's payroll department. What is your assessment?
What is a DKIM replay attack, and why does it bypass authentication checks?
When triaging a suspicious email in Lab 4.2, you see dmarc=pass in the Authentication-Results. Can you conclude the email is safe?
0/10 answered