agentleFS
GoldenWing-360GoldenWing-360/claude-security-skills/dns-domain-security/SKILL.md

dns-domain-security

Skill16 starsChanged 6 months agoMITView on GitHub

Secure the DNS and domain layer below TLS — the records, registrar, and provider access everyone forgets. Covers dangling records and subdomain takeover, registrar hardening and transfer locks, CAA, DNSSEC trade-offs, zone hygiene, split-horizon leakage, scoped DNS API tokens, and CT-log monitoring. Invoke when auditing a zone, when a domain or registrar account changes hands, or after decommissioning a SaaS service a CNAME pointed at.

The file

We split this skill into the rules it gives an agent

7 rules. About 0 are common, 5 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Remediation is deletion: If a record's target is gone, the record goes too — same change window, ideally the same deprovisioning checklist.

    line 73
  2. Distinctive:

    Prefer providers with fully managed DNSSEC (automatic rollovers, one-click DS via registrar integration)

    line 128
  3. Distinctive:

    Verify after any change:

    line 130
  4. Distinctive:

    If your provider only offers manual DNSSEC and you have no monitoring for it, enabling it can be a net risk increase.

    line 137
  5. Very specific:

    Comment/tag records at the provider: if supported — owner=platform-team, reason=acme-dns01, added=2026-08 turns future audits from …

    line 151
  6. Very specific:

    Keep internal names in a separate internal zone (internal.example.com served only by internal resolvers, or a distinct private domain) — …

    line 157
  7. Distinctive:

    Before planned migrations, drop the TTL one full old-TTL period in advance, migrate, then raise it back.

    line 193

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

DNS & Domain Security

Everything above DNS assumes DNS is telling the truth. TLS certificates are issued based on DNS-validated control, email authentication lives in TXT records, and your entire brand hangs off a registrar login. Yet the DNS layer usually gets one setup session at launch and then years of unreviewed drift: records pointing at services that no longer exist, a registrar account with a password from 2019, and API tokens with zone-wide write access baked into three CI pipelines.

This skill audits and hardens that layer. The recurring theme is lifecycle: DNS records outlive the things they point to, and every orphaned pointer is a liability someone else can pick up.

When to invoke

  • Periodic audit of a zone you operate (quarterly is a good cadence)
  • A SaaS service, PaaS app, or static-hosting project was decommissioned — did its DNS records go with it?
  • Domain or registrar account is changing hands (team member left, agency handover, acquisition)
  • A certificate appeared in CT logs that nobody requested
  • Setting up DNS automation (CI, ACME DNS-01, dynamic records) and deciding token scope
  • A domain in the portfolio is approaching expiry

The threat map

LayerAttackPrimary control
Registrar accountCredential stuffing, social-engineered transferMFA (hardware key), transfer lock, registry lock
Domain lifecycleExpiry → re-registration by attackerAuto-renew, expiry monitoring, long registration
Zone contentDangling CNAME → subdomain takeoverStale-record audits, deprovision checklist
Certificate issuanceUnauthorized cert from any public CACAA records, CT-log monitoring
Resolution integrityCache poisoning, spoofed responsesDNSSEC (with operational care)
Provider APILeaked token rewrites the zonePer-zone scoped tokens, rotation

Registrar compromise sits above everything: an attacker who controls the registrar account controls NS delegation, and from there every record, every cert, every mailbox. Harden top-down.

Dangling records and subdomain takeover

A dangling record points at a resource you no longer control. The classic case: app.example.com is a CNAME to a PaaS or SaaS endpoint, the project gets deleted, the CNAME stays. On many providers, anyone can then claim that endpoint name and serve content — with a valid certificate — on your subdomain. That is a phishing page, cookie-scoped script host, or OAuth redirect target wearing your domain.

The same applies to A/AAAA records pointing at released cloud IPs, NS records delegating to a decommissioned nameserver, and MX records at a cancelled mail provider.

Audit the zone for danglers

Export the zone from your provider (API or panel), then walk every CNAME target:

# zone.txt: one "name type target" per line, exported from your DNS provider
awk '$2 == "CNAME" {print $1, $3}' zone.txt | while read -r name target; do
  status=$(dig +short "$target" A | head -1)
  if [ -z "$status" ]; then
    echo "DANGLING? $name -> $target (no A record for target)"
  fi
done

A CNAME whose target does not resolve (NXDOMAIN) is the loudest signal — on several SaaS platforms that exact state means "claimable". But resolving is not proof of safety: a target that resolves to the provider's shared ingress while returning the provider's "no such app / unknown domain" error page is often claimable too. Follow up on every CNAME to a third-party platform:

awk '$2 == "CNAME" {print $1}' zone.txt | while read -r name; do
  code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 "https://$name/")
  echo "$name -> HTTP $code"
done
# 404 / 502 / provider error page on a name you "own" = investigate immediately

And check A/AAAA records against infrastructure you still hold:

awk '$2 == "A" {print $1, $3}' zone.txt | while read -r name ip; do
  # Compare against your current inventory of owned IPs
  grep -q "^$ip$" owned-ips.txt || echo "ORPHAN IP: $name -> $ip"
done

Remediation is deletion. If a record's target is gone, the record goes too — same change window, ideally the same deprovisioning checklist. Make "remove DNS records" a mandatory step in every service-teardown runbook; that is the systemic fix.

Registrar account hardening

The registrar account is the root of trust for the whole domain. Treat it like a production root credential.

  • MFA with a hardware key or TOTP — never SMS; SIM-swap against a registrar account is a well-worn path
  • Unique, vaulted password — this account must not share credentials with anything
  • Transfer lock (clientTransferProhibited) on every domain — verify with whois, don't trust the panel:
whois example.com | grep -i 'status'
# want: clientTransferProhibited (and clientDeleteProhibited / clientUpdateProhibited where offered)
  • Registry lock for high-value domains — a paid, manual-verification lock at the registry itself; changes require an out-of-band ceremony. Worth it for the domain your business runs on.
  • Expiry is an account-takeover path. A lapsed domain gets re-registered by drop-catchers within minutes; the new owner receives your password resets, your mail, your OAuth callbacks. Auto-renew on, payment method current, and independent expiry monitoring:
whois example.com | grep -i 'expiry\|expiration'
# Alert at 60 and 30 days out — do not rely on registrar reminder emails alone
  • Registrant contact email must not be on the domain itself — if example.com breaks, the reset email for its own registrar account must still arrive
  • WHOIS privacy on, unless a compliance regime requires published contacts

CAA — restrict who may issue certificates

CAA records tell certificate authorities which of them may issue for your domain. Without CAA, any publicly trusted CA will issue to anyone who can pass domain validation — which, combined with a dangling record or DNS hijack, becomes a valid cert on your name.

example.com.   CAA   0 issue "letsencrypt.org"
example.com.   CAA   0 issue "pki.goog"
example.com.   CAA   0 issuewild ";"
example.com.   CAA   0 iodef "mailto:security@example.com"
  • issue — enumerate exactly the CAs you actually use (check your CDN/proxy's docs; they often issue via their own CA partners)
  • issuewild ";" — forbid wildcard issuance entirely unless you deliberately use wildcards
  • iodef — some CAs will report refused issuance attempts here
dig +short CAA example.com

CAA is checked at issuance time only — it does not revoke existing certs, and a CA that ignores the spec is a CA-compromise scenario, not something CAA solves. It is cheap, standard, and closes the "any CA, any attacker with DV" gap. Set it on every zone.

DNSSEC — what it buys and what it costs

DNSSEC cryptographically signs your zone so resolvers can verify responses were not forged in transit. It protects against cache poisoning and off-path spoofing of your zone's data.

What it does not do: encrypt queries (that's DoH/DoT, a resolver-side concern), protect against a compromised registrar or DNS provider (they hold the keys), or help clients whose resolvers don't validate.

The operational risk is real: a botched key rollover or a DS record left at the registrar after switching DNS providers makes your zone hard-fail for every validating resolver — a self-inflicted outage that plain DNS cannot have.

  • Prefer providers with fully managed DNSSEC (automatic rollovers, one-click DS via registrar integration)
  • When migrating DNS providers, remove the DS record at the registrar first, wait out the TTL, then move — the top DNSSEC outage cause is a stale DS pointing at the old provider's keys
  • Verify after any change:
dig +dnssec example.com A | grep -E 'RRSIG|flags'   # want RRSIG present, ad flag from a validating resolver
dig +short DS example.com @198.51.100.1              # DS at the parent must match current keys

If your provider only offers manual DNSSEC and you have no monitoring for it, enabling it can be a net risk increase. Decide deliberately; don't cargo-cult it on.

Zone hygiene

  • Wildcards (*.example.com) — a wildcard A/CNAME makes every nonexistent subdomain resolve. That widens cookie scope abuse, makes takeover-style phishing names (login-secure.example.com) resolve without the attacker touching your zone, and defeats dangling-record auditing because nothing ever NXDOMAINs. Enumerate real hostnames explicitly; reserve wildcards for platforms that genuinely need them, on a dedicated subdomain tier.
  • Stale-record inventory — every record should have a known owner and purpose. If nobody can say what legacy-api.example.com is for, resolve that before an attacker does.
  • TXT sprawl — TXT records accumulate: site-verification tokens for tools abandoned years ago, SPF includes for departed ESPs, ad-hoc key material. Each one leaks which vendors you use (recon gold) and some (stale verification tokens, stale SPF includes) grant standing capability to whoever controls the referenced service. Dump and prune:
dig +short TXT example.com
dig +short TXT _dmarc.example.com
# For each verification token: is the tool still in use? If not, delete.
  • Comment/tag records at the provider if supported — owner=platform-team, reason=acme-dns01, added=2026-08 turns future audits from archaeology into a diff.

Split-horizon and internal hostname leakage

Internal infrastructure names do not belong in public zones. vpn.example.com, jenkins.example.com, db-primary.example.com resolving publicly — even to RFC 1918 addresses — hands attackers a labeled network map for free.

  • Keep internal names in a separate internal zone (internal.example.com served only by internal resolvers, or a distinct private domain) — true split-horizon, not public records with private IPs
  • Remember that certificates leak names too: a cert requested for an internal hostname via a public CA lands in CT logs forever. Use a wildcard cert at a boundary name, or an internal CA, for hosts that should stay unlisted.
  • Audit what's already public: your zone export is the attacker's enumeration result. Read it with that lens — every name that surprises you would delight them.

DNS provider access control

The DNS provider account and its API tokens can rewrite reality for your domain. Common failure: one account-wide "DNS edit everything" token pasted into CI for a single ACME DNS-01 challenge.

  • One token per automation, scoped to one zone, minimum permissions (edit TXT only, if the provider supports record-type scoping)
  • For ACME specifically, prefer CNAME-delegated challenges (_acme-challenge.example.com CNAME to a dedicated throwaway zone) so the token only touches that zone
  • Rotate tokens on a schedule and immediately on any pipeline compromise; keep an inventory of which token lives where
  • Provider account itself: MFA, audit log reviewed, humans and automation as separate members — the same discipline as the registrar
  • Zone changes belong in change control: provider audit log at minimum, zone-as-code (Terraform/OctoDNS) with review if the zone is large enough to drift

Monitoring

DNS problems are silent until exploited. Two external signals cover most of it:

  • Certificate Transparency logs — every publicly trusted cert is logged. Watch your domains for issuance you didn't initiate; an unexpected cert is the earliest visible sign of a takeover or hijack in progress. Free watchers exist (e.g. crt.sh-based alerting, CA-provided CT monitors); spot-check manually:
curl -s "https://crt.sh/?q=%25.example.com&output=json" \
  | python3 -c 'import json,sys; [print(e["name_value"], e["not_before"]) for e in json.load(sys.stdin)]' \
  | sort -u | tail -30
  • Passive DNS — services that record what names resolved to over time. Useful for spotting a subdomain of yours suddenly resolving somewhere new (takeover detection) and for reconstructing what a deleted record used to point at during incident response.
  • Scheduled self-checks — cron the dangling-CNAME loop, the whois expiry/lock check, and a diff of the zone export against the last known-good copy. A zone diff landing in a chat channel weekly costs nothing and catches both drift and tampering.

TTL strategy

TTLs are an incident-response parameter disguised as a performance knob.

  • Low TTL (60–300 s) on records you may need to move fast — app endpoints, anything with a failover story. During an incident, a 24 h TTL means a full day of clients still resolving the compromised or dead target.
  • Higher TTL (1–24 h) is fine for stable plumbing — MX, TXT/SPF, NS glue that changes rarely.
  • The "low TTL helps attackers" worry is mostly misplaced: an attacker who can change your records can also change your TTLs. Low TTL on the legitimate record mainly determines how fast you can recover — a hijacked record with a long TTL keeps poisoning caches long after you fix the zone. Bias toward agility on anything user-facing.
  • Before planned migrations, drop the TTL one full old-TTL period in advance, migrate, then raise it back.

Quick checklist

  • Registrar: MFA (non-SMS), unique vaulted password, reset email off-domain
  • whois shows clientTransferProhibited on every domain; registry lock on crown-jewel domains
  • Auto-renew on + independent expiry alerts at 60/30 days
  • Zone exported; every record has a known owner and purpose
  • Dangling-CNAME audit run; all CNAMEs to third-party platforms verified claimed-by-us
  • A/AAAA records cross-checked against currently-owned IP inventory
  • No wildcard records without a deliberate reason
  • TXT records pruned; stale verification tokens and SPF includes removed
  • CAA present: issue for actual CAs only, issuewild ";" if no wildcards, iodef set
  • DNSSEC decision made deliberately; if on, managed rollovers + DS verified; if migrating providers, DS removal sequenced first
  • No internal hostnames in public zones; internal names on internal resolvers; no internal names in CT via public CAs
  • DNS API tokens: per-zone, minimal permissions, inventoried, rotation schedule
  • CT-log monitoring active for all domains
  • Dangling-record and zone-diff checks scheduled, not one-off
  • TTLs: low on movable endpoints, deliberate everywhere else
  • Service-teardown runbooks include "delete the DNS records"

What this skill will not do

  • Help claim, probe, or "test" a dangling subdomain on a domain you do not own — takeover checks are for your own zones only
  • Assist with domain transfer, WHOIS manipulation, or registrar access for domains you do not control
  • Recommend disabling DNSSEC purely to avoid operational effort where managed tooling exists — the trade-off must be argued, not defaulted
  • Enumerate or fingerprint third-party zones beyond what auditing your own delegations requires

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.