The Sender Nobody Owns: Walking an SPF Include Tree to NXDOMAIN

Network & Infrastructure Level 3/4 ~5 min September 23, 2026

The challenge

Three of Meridian's customers paid an invoice that Meridian never sent, and the fake mail passed SPF. Nobody touched the mail servers, so the answer is in the DNS. Meridian's SPF record delegates to other senders with include:, and each of those records can delegate again. Walk the tree until one lookup comes back NXDOMAIN. That name is unregistered, which means anybody can register it, publish an SPF record on it, and send mail that authenticates as Meridian. Name it.

What you'll learn

  • Resolve an SPF record and follow every include: to its own record
  • Recognise NXDOMAIN on an include as a takeover-ready delegation
  • Explain why a vendor's SPF record is part of your own attack surface
  • Use dig to walk a delegation tree one name at a time
  • Connect vendor offboarding to authentication failures months later

Skills tested

DNS enumerationEmail authentication analysisSupply-chain reasoning

Prerequisites

  • What a DNS TXT record is
  • Basic familiarity with dig

How it works

An SPF record answers one question: which hosts may send mail for this domain. The answer is rarely written in one place. include: tells the evaluator to go and read somebody else's SPF record and treat its result as part of yours, and that record is free to contain includes of its own. What looks like a single line in your zone is a tree that can be four or five lookups deep, most of it published by companies you do not control.

A branch of that tree stops being safe the moment a name in it stops resolving. NXDOMAIN is not a failure that closes the door: it means nobody owns the name. Anyone can register it, publish v=spf1 +all, and every SPF evaluator in the world will walk from your domain into their record and return a pass. The victim domain's own DNS is untouched and perfect, which is why the team that owns it usually looks at everything except the tree.

Vendor offboarding is where these appear. The contract ends, the account closes, the domain lapses at renewal, and the include that pointed at it stays in a record that a third party maintains. Nothing breaks visibly, so nothing gets cleaned up.

Common mistakes

  • Stopping at the first record. The three includes in meridian.example are the question, not the answer. Two are leaves; one delegates again.
  • Answering spf.mailhive.example. MailHive resolves fine and is a live vendor. It is the record that carries the broken include, not the broken name.
  • Reading only the ANSWER SECTION. A dead lookup has no answer section at all. The finding is on the status: line of the header.
  • Assuming the mail servers were compromised. Nothing was. SPF passed honestly, for a sender the record genuinely authorises.

How to defend against it

Treat the include tree as inventory, not configuration.

  • Resolve every include recursively on a schedule and alert on any name that returns NXDOMAIN or SERVFAIL. This is a few lines of script and it catches the problem the day the domain lapses.
  • Put DNS delegation removal on the vendor offboarding checklist next to revoking API keys, and include the vendor's own records where they name you.
  • Publish DMARC with a policy and collect the aggregate reports. A spoofing run that passes SPF from an unfamiliar network still shows up there with a source you do not recognise.
  • Keep the lookup count low. SPF allows ten DNS lookups; a shallow record is both faster and much easier to audit.

Full solution

Pro and Max members unlock the complete step-by-step walkthrough.

Go Pro

Community stats

116 completions
75% success rate
Malekith First blood

Related Daily Hacks

28,000+ Hackers 100+ Labs & Courses Free
Start Hacking Free