The Ghost in the TXT Record: Exploiting Dangling SPF Includes
A forgotten line in your SPF record isn't just technical debt—it's a pre-authenticated backdoor for business email compromise.

The alert hits your queue at 4:52 PM on a Friday. It’s a high-priority flag from the finance department. The CFO received an email from the CEO, who is currently on a flight to Tokyo, asking for an urgent wire transfer to a new vendor. Standard BEC procedure, except for one terrifying detail: every authentication check passed. SPF, DKIM alignment, DMARC. The email didn't just look like it came from your domain. According to every receiving mail server on the planet, it was legitimate.
This isn't a case of a compromised account or a sophisticated zero-day in your email gateway. The vulnerability wasn't in your infrastructure at all. It was in your DNS, hiding in plain sight as a single, forgotten line in your SPF record.
The attacker didn’t have to break your security. You handed them the keys months, or even years, ago when you decommissioned a SaaS tool but forgot to clean up the corresponding TXT record. This is the anatomy of a dangling SPF record exploit.
Attack Scenario: An Undead SaaS Vendor Sends the Invoice
Let's make this concrete. Imagine your company, ExampleCorp, used a marketing analytics service called 'Chartifytics' back in 2021. When you onboarded them, your IT admin dutifully modified ExampleCorp's SPF record in DNS to authorize their mail servers. The record was updated to include: `include:mail.chartifytics.io`.
The RFC 7208 specification for SPF dictates that this `include` mechanism triggers a recursive lookup. Any mail server checking ExampleCorp's SPF policy will also query the SPF record for `mail.chartifytics.io` and trust whatever IPs it finds there. For a time, this worked perfectly, allowing Chartifytics to send email reports on your behalf.
But two years later, Chartifytics goes out of business. Their domain, `chartifytics.io`, expires and becomes available for public registration. Crucially, nobody at ExampleCorp remembers to remove the `include:mail.chartifytics.io` from the live SPF record. It's a piece of dormant, harmless-looking text. Technical debt.
Until it's not. An attacker, methodically scanning for just this kind of oversight, discovers the expired domain. They register `chartifytics.io` for $12. They now control a domain that your organization has explicitly designated as a trusted sender. The stage is set for a perfectly authenticated phishing attack.
Reconnaissance: Finding the Cracks in the Armor
Attackers aren't guessing. They find these dangling SPF record exploits through systematic reconnaissance. It's an automated, low-effort/high-reward process that weaponizes public DNS information.
Recursive SPF Unraveling
The first step is to enumerate all domains trusted by a target's SPF policy. This begins with a simple DNS query.
$ dig aol.com TXT +short
"v=spf1 ptr:mx.aol.com include:spf.constantcontact.com include:spf-aol.google.com include:sendgrid.net -all"
From this single command, an attacker has a list of initial domains to investigate: `mx.aol.com` (via the `ptr` mechanism), `spf.constantcontact.com`, `spf-aol.google.com`, and `sendgrid.net`. They then recursively query the SPF records for each of these included domains, walking the entire trust chain and building a comprehensive list of every domain authorized to send email on behalf of aol.com. This can be scripted to map out dozens of dependencies in seconds.
Hunting for Expirations
With a complete list of included domains, the attacker simply automates WHOIS lookups for each one, parsing the output for the domain's expiration date. A simple shell one-liner can check a list of domains and flag any that are unregistered or have recently expired. This is exactly how they'd find `chartifytics.io` sitting in your SPF record, ready for takeover. Attackers aren't just looking for `include` mechanisms. They hunt for stale `a`, `mx`, and even `exists` mechanisms that point to domains or hosts that have been decommissioned but not removed from the policy.
Weaponization: Raising a Phishing Platform on Hallowed Ground
Once an attacker has identified an expired, included domain, weaponization is trivial. They aren't hacking a server; they're simply claiming abandoned digital property and telling the world's email infrastructure that they belong.
First, the attacker registers the expired domain, `chartifytics.io`, through a standard registrar. This gives them full control over its DNS records. Second, they deploy a basic mail server (MTA) like Postfix or OpenSMTPD on a cheap virtual private server (VPS). Let's say its IP is `198.51.100.23`.
Here's the critical step. The attacker creates a new TXT record for `chartifytics.io` and populates it with their own malicious SPF policy. It could be as simple as:
v=spf1 ip4:198.51.100.23 -all
Now, let's trace the logic. When the CFO's mail server receives the fraudulent wire transfer email from `ceo@examplecorp.com` (which originated from the attacker's server at `198.51.100.23`), it performs an SPF check. It queries `examplecorp.com`, finds `include:mail.chartifytics.io`, and recursively queries `mail.chartifytics.io`. The attacker controls this, pointing it to `chartifytics.io`. That record now resolves to `v=spf1 ip4:198.51.100.23 -all`. The source IP `198.51.100.23` is on the list. The result is an unequivocal `spf=pass`. The email is authentic as far as the protocol is concerned.
The Forensic Trail: Pinpointing the Compromised 'include'
As a SOC analyst, this is where you earn your coffee. The ticket is in, the damage is done, and you need to find out how an attacker sent a fully authenticated email from your own domain. The raw email headers are your ground truth.
Dissecting the Authentication-Results Header
The first place to look is the `Authentication-Results` header, inserted by the primary receiving mail server (e.g., Google, Microsoft). It gives you a summary of the authentication verdicts. In our scenario, it would look disturbingly good:
Authentication-Results: mx.google.com; dkim=pass header.i=@examplecorp.com; spf=pass (google.com: domain of ceo@examplecorp.com designates 198.51.100.23 as permitted sender) smtp.mailfrom=ceo@examplecorp.com; dmarc=pass (p=reject dis=none) header.from=examplecorp.com — Header snippet from a recipient at Gmail
The `dkim=pass` might happen if the attacker also set up DKIM on their malicious domain, or it could fail—but a `spf=pass` with an aligned `header.from` is often enough to get a `dmarc=pass`. The key forensic artifact here is `spf=pass ... designates 198.51.100.23 as permitted sender`. This is the smoking gun. That IP is not one of your known corporate mail servers.
Connecting IPs to SPF Policies
Your next step is to answer: why did we authorize `198.51.100.23`? You must now perform the same reconnaissance the attacker did. Pull your own domain's SPF record. List every `include`, `a`, `mx`, and `exists` mechanism. Then, one by one, resolve them. You are looking for the policy that contains the IP `198.51.100.23`. When you get to `include:mail.chartifytics.io` and resolve its SPF record, you'll find the attacker's `ip4` entry. You've found the root cause. This manual, recursive process of cross-referencing `Received` headers and `Authentication-Results` IPs against your own SPF logic is the core of the investigation.
Proactive Defense: A Workflow for Auditing Stale Records
Post-incident forensics is valuable, but proactive defense is better. An SPF record is not a static piece of configuration; it's a dynamic list of trusted third parties that you are vouching for. It requires regular audits.
You can build a simple script to automate the discovery of potentially dangling records. The logic is straightforward: recursively resolve your full SPF policy to get a flat list of every domain, subdomain, and IP address. For every domain in the list, perform a WHOIS lookup and check the expiration date. Flag any domains that are unregistered, expired, or expiring within the next 90 days. This gives your team a chance to investigate and remove the unnecessary `include` before it becomes a weapon.
This audit also helps manage the dreaded '10 DNS lookup limit' imposed by RFC 7208. Over time, SPF records accumulate entries, and complex nesting can easily cause you to exceed this limit, leading to `permerror` results and legitimate mail failing authentication. Auditing forces you to justify each entry and remove the ones that are no longer needed, for both security and deliverability reasons.
A manual audit is a great start, but it's tedious and easy to forget. The only sustainable solution is automation. Don't let your public DNS records become a graveyard of forgotten partnerships.
The takeaway
An SPF record is an extension of your security perimeter. Every `include` is a gate you've opened, trusting another organization to maintain it securely. When they fail to do so, or when the partnership simply ends, that open gate becomes your liability. A dangling SPF record exploit is not a complex hack; it's a failure of hygiene, and it's brutally effective.
This kind of deep, recursive DNS analysis is precisely what platforms like MailSleuth.AI automate, turning a painful manual chore into a continuous security check. Regardless of the tool, the principle stands: go read your SPF record. Right now. Do you know, with certainty, who owns every single domain you're including?
We dissect phishing campaigns and email infrastructure so you don't have to.


