Skip to content

LearnIdentity

SPF, DKIM and DMARC as a tester reads them

Reading a domain's SPF, DKIM and DMARC records the way a tester does: what each one lets an attacker send as you, and the record that closes it.

Area
Identity
Stage
Recon
Reviewed
On this page
  1. What to check first
  2. Read DMARC
  3. Read SPF
  4. Find the DKIM selectors
  5. Lock parked domains
  6. Test email spoofing
  7. What the defender sees
  8. Tools
  9. Related research

Email authentication records are public, so this is one of the few checks we can complete before a test starts. The question we answer is narrow: can someone send mail that shows the client's exact domain in the From line and reach an inbox? Lookalike domains are a separate problem, and these records do nothing about them.

What to check first

  • The DMARC policy on the apex domain, the subdomain policy, and the percentage it applies to.
  • The SPF record's final all term and how many DNS lookups it costs.
  • Which DKIM selectors are live, taken from real message headers rather than guessed.
  • Parked and unused domains, which need a reject policy as much as the main one.
  • Whether mail can reach the mail platform directly, around the filtering gateway named in MX.

Read DMARC

dig +short TXT _dmarc.example.com

p=none asks receivers to take no action: a spoofed message from the exact domain is judged as if no record existed, and if the record has a rua= address, the owner gets an aggregate report about it afterwards. p=quarantine with pct=10 applies to one message in ten. A missing sp= means subdomains inherit the main policy, and an explicit sp=none leaves every subdomain open even when the apex is set to reject.

Fix. Read the aggregate reports until every legitimate sender passes, then move to p=reject with sp=reject and no pct below 100. A domain that has sat at p=none for a year is not monitoring anything; it is waiting.

Read SPF

dig +short TXT example.com | grep -i 'v=spf1'
checkdmarc example.com

We read three things. The final term: -all fails unlisted senders, ~all soft fails them, ?all returns neutral, which says nothing either way, and +all lets any server on the internet pass. The lookup count: SPF allows ten DNS lookups, and a record over the limit returns a permanent error that many receivers treat as no SPF at all. And the includes: every include: is a vendor that can send as the domain, and the client should be able to name each one.

Fix. Remove vendors you no longer use, keep the record under ten lookups, and end it with -all, or ~all when DMARC is already at reject. Give bulk senders their own subdomain so their SPF and reputation stay separate from your staff mail.

Find the DKIM selectors

DKIM selectors are not listed anywhere, so we take them from real mail: the scoping emails the client sent us, or a newsletter. The DKIM-Signature header carries s= for the selector and d= for the signing domain.

dig +short TXT selector1._domainkey.example.com

We note the key size and any selectors for vendors the client says they have left. A public key still in DNS means mail signed with its private key still verifies, wherever that key now lives.

Fix. Use 2048-bit keys, rotate them on a schedule, and delete the DNS record for any selector belonging to a vendor you have left.

Lock parked domains

Domains that never send mail are the easiest to spoof because nobody watches them. Three records close them:

parked.example.com.         TXT  "v=spf1 -all"
_dmarc.parked.example.com.  TXT  "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s"
parked.example.com.         MX   0 .

Fix. Publish those three on every domain you own that does not send mail, including old brand names and typo domains you registered defensively.

Test email spoofing

With the client's approval, we send one message to a test mailbox they control, with the From header set to their domain, from infrastructure of ours that is not in their SPF record. Then we read what the receiving server decided:

Authentication-Results: mx.example.com;
  spf=fail smtp.mailfrom=sender.tester.example;
  dkim=none;
  dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=example.com

If that message lands in the inbox, the finding writes itself. If the mail platform accepts delivery straight from the internet, we repeat the test against it directly, because a filtering gateway that can be bypassed is not filtering.

Fix. Restrict inbound delivery on the mail platform to the gateway's addresses, so the gateway in MX is the only way in.

atarus-phishcheck checks the SPF, DKIM and DMARC results in a message's headers alongside the live DNS records, and the client can run it on their own suspicious mail after we leave.

What the defender sees

The DNS lookups go through a public resolver, so if the client's authoritative name servers log queries at all, they record the resolver's address, not ours. The test message shows in the client's DMARC aggregate reports a day later, which is a useful check that someone reads them.