Subdomain Spoofing Is Your Blind Spot. Here's a DMARC Fix.
Your DMARC policy is only as strong as its subdomain configuration—attackers are counting on you getting it wrong.

An attacker finds `staging.yourcorp.net` in a public certificate transparency log. A quick DNS check shows no MX records, no SPF, and certainly no DMARC. It's a ghost town. But the parent domain, `yourcorp.net`, is a fortress. Too bad. The attacker doesn't need to break in; they just need to borrow the address. They spin up a mail server and start sending CEO fraud emails from `ceo@staging.yourcorp.net`. To a receiving mail server, it looks plausible enough. The domain is legitimate, after all.
This isn't a hypothetical. It's a daily incident response headache. We sweat the details of our primary domain's DMARC policy, getting `p=reject` to protect our brand, only to leave dozens of subdomains exposed. Every `dev`, `uat`, `test`, `marketing`, and forgotten project subdomain is a potential platform for a business email compromise (BEC) attack.
Securing them requires moving beyond a simple parent-level policy. It demands a specific, layered strategy for subdomains. Let's get it right.
The `sp` Tag Is Your Most Important Subdomain Control
Most DMARC deployments focus exclusively on the `p=` tag, which sets the policy for the organizational domain. You set `p=reject` and feel secure. But DMARC, as defined in RFC 7489, has a separate tag for subdomains: `sp=`, the subdomain policy tag. If you don't explicitly set it, it inherits the value of the `p=` tag. While that sounds safe, it creates operational friction that causes people to implement weaker policies.
Imagine your primary domain, `example.com`, is at `p=reject`. Without an `sp` tag, `any.subdomain.example.com` also inherits `p=reject`. Now, what happens when your marketing team signs up for a new mail provider that sends from `email.example.com` but hasn't had its IPs and DKIM keys added to your configuration? Mail gets rejected. The business screams. The common, and wrong, reaction is to downgrade the primary `p=` policy to `quarantine` or `none` to let the marketing mail through, weakening security for everyone.
Explicitly Defining Subdomain Policy
The correct pattern is to be explicit. Set a strong policy for the organizational domain, and a separate, explicit policy for all subdomains. This gives you flexibility. For most organizations, the vast majority of subdomains do not send email. At all.
The goal state for your primary DMARC record should look like this:
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc-agg@example.com;
This DNS TXT record at `_dmarc.example.com` tells receivers: "Reject any mail claiming to be from `example.com` that fails DMARC. Also, reject any mail claiming to be from `any.subdomain.example.com` that fails DMARC." This is your baseline: deny all, then allow by exception. If a specific subdomain *does* need to send mail, like `marketing.example.com`, you give it its own DMARC policy that overrides the parent `sp=` tag. This is the surgical approach.
Block Hijacking with Defensive Subdomain Records
Setting `sp=reject` is a great start. But a determined attacker can sometimes find a way around it. DMARC works by checking for a policy at the subdomain level first (`_dmarc.marketing.example.com`) and only then falling back to the organizational domain's policy (`_dmarc.example.com`). This creates a niche attack vector.
The DMARC Preemption Attack
If an attacker compromises the DNS for a non-sending subdomain—let's say `assets.example.com`—they can publish their own, weaker DMARC record there. They could create a TXT record at `_dmarc.assets.example.com` with the value `v=DMARC1; p=none;`. A receiving mail server checking a spoofed email from `sender@assets.example.com` would find this new policy and stop searching. It would honor the `p=none` policy, completely ignoring your organizational `sp=reject` tag. The attacker has successfully preempted your security control.
The Wildcard Countermeasure
The defense is to squat on your own DNS. For every subdomain that should never send mail, you should create a DMARC record explicitly telling the world that. But creating records for hundreds of subdomains is an operational nightmare. Instead, you can use a wildcard DNS record.
Create a TXT record at `*._dmarc.example.com` with the value `v=DMARC1; p=reject;`. This single record provides a DMARC policy for any subdomain that doesn't have an explicit one defined. It's a powerful and efficient way to enforce a 'deny by default' posture across your entire namespace, preventing an attacker from inserting a weak policy on a compromised subdomain.
Ditch the Monolithic SPF Record
The `sp=reject` policy relies on SPF or DKIM alignment failing. For non-sending subdomains, the easiest way to guarantee failure is a hardfail SPF record. Just like with DMARC, applying this granularly is superior to a single, overloaded record at the root.
The classic mistake is stuffing every third-party IP and domain include into one massive SPF TXT record on your organizational domain. This quickly blows past the 10-DNS-lookup limit imposed by RFC 7208. Once you exceed 10 lookups (from `include`, `a`, `mx`, `ptr`, or `exists` mechanisms), SPF evaluation results in a `permerror`. Most receivers treat `permerror` as a fail, but some treat it as neutral, potentially weakening your DMARC posture.
SPF Records Belong to Sending Subdomains
The better architectural pattern is to delegate. Your organizational domain's SPF record should be minimal, perhaps even `v=spf1 -all` if the root domain itself sends no mail. Each subdomain that legitimately sends email should have its own SPF record.
For `marketing.example.com`, which uses Salesforce and Marketo, the TXT record at `marketing.example.com` would be `v=spf1 include:salesforce.com include:marketo.com -all`. For `support.example.com`, which uses Zendesk, its record would be `v=spf1 include:mail.zendesk.com -all`. This isolates sender reputation, simplifies auditing, and makes it nearly impossible to exceed the 10-lookup limit on any single record.
For the vast majority of non-sending subdomains, you enforce `sp=reject` with a simple, powerful SPF record at the subdomain level: `v=spf1 -all`. This explicitly states that no hosts are authorized to send mail for this subdomain, guaranteeing an SPF `fail` verdict.
Isolate Senders with Granular DKIM Keys
The same principle of isolation applies to DKIM. Using a single DKIM key, managed under a single selector like `default._domainkey.example.com`, for all your mail streams is a concentration of risk. If that private key is compromised—say, from a less-secure third-party provider—an attacker can sign fraudulent mail that will pass DKIM validation and, if the domain aligns, DMARC.
DKIM, as defined in RFC 6376, provides two key labels for namespacing: the signing domain (`d=`) and the selector (`s=`). You must use them to your advantage. Each third-party service and internal sending system should have its own unique DKIM key, published under a unique selector and tied to the specific subdomain it sends from.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=support.example.com; s=zendesk1; ... — Example Authentication-Results Header
In this header, the signing domain is `d=support.example.com` and the selector is `s=zendesk1`. The public key is retrieved from DNS at `zendesk1._domainkey.support.example.com`. This setup is beautiful. If the Zendesk key is ever compromised, you can revoke it instantly without impacting your transactional mail from Postmark or your corporate mail from Google Workspace. It also means a compromise of your Zendesk account doesn't allow an attacker to sign mail as `ceo@example.com`.
This containment is the entire point. It turns a potentially domain-wide catastrophe into a contained, manageable incident for a single service on a single subdomain.
How to Run a Subdomain Security Audit
You can't protect what you don't know you have. The first step in this strategy is discovery. You need a comprehensive list of all your company's subdomains. Don't just ask IT for a zone file; that's often incomplete. You need to combine data from multiple sources: internal DNS zone files, public Certificate Transparency logs, web crawling tools, and passive DNS history.
Once you have your list, you can automate the audit. For every discovered subdomain, your process should check for the following DNS records:
The Subdomain Audit Checklist
First, query for `_dmarc.[subdomain]`. Does it have its own DMARC policy? If not, you need to know what the organizational DMARC record's `sp=` tag is. Any subdomain without an explicit policy under a weak or missing `sp=` tag is a finding.
Second, query for an `MX` record. A subdomain with an MX record is designed to receive email. This implies it might also send email, and it needs stricter scrutiny. A subdomain with no MX records is less likely to be a legitimate mail sender.
Third, query for a `TXT` record for SPF. Is there one? If not, it's a gap. If there is, what does it say? An SPF record of `v=spf1 -all` is a strong signal that the subdomain shouldn't be sending mail. Anything else warrants investigation. Who are those authorized senders? Are they still in use?
The goal is to produce a prioritized list of subdomains that are misconfigured. Any subdomain that could be used to send email but lacks a `p=reject` or `sp=reject` DMARC policy, or has a permissive SPF record, is a high-priority target for remediation.
The takeaway
Treating all subdomains as hostile until proven otherwise is the only sane security posture. Your default state should be `sp=reject`, enforced by a `v=spf1 -all` record deployed via wildcard or on a per-subdomain basis. Legitimate senders are the exception, not the rule. Each one should get its own subdomain, its own specific SPF policy, and its own unique DKIM key.
This isn't just about passing an email authentication check. It's about building a defensible architecture that contains failures and gives you precise control over who can speak on your organization's behalf. It makes your DMARC reports cleaner and your incident response playbook simpler. Continuously auditing your subdomains against this model, with tools that can automate the discovery and DNS lookups, is a fundamental practice of modern email security defense. The attackers are already doing it.
We dissect phishing campaigns and email infrastructure so you don't have to.


