attacker-controlled-site.com
Published 2026-07-25

Dangling references: domains still wired into your systems

SPF includes, OAuth callbacks, webhooks and package metadata all name domains. Some of those names are no longer controlled by anyone you trust.

A dangling reference is a pointer to a name you no longer control, sitting in a system that still trusts it.

The pattern is always the same. Something in your infrastructure names a domain. That domain changes hands — it expires, a vendor shuts down, a subsidiary is sold, a contractor’s side project lapses. Your configuration does not notice, because configuration has no way to notice. It keeps resolving the name, and the name now answers to somebody else.

Unlike a broken link, this does not fail loudly. It keeps working, which is the problem.

Where they hide

SPF includes

An SPF record delegates sending authority with include:. Every included domain gets a say in who may send mail as you, and includes can nest several levels deep, so the effective list is usually longer than the one you wrote.

If any domain in that chain lapses and is re-registered, the new owner inherits that delegation. You will not see it in your own DNS, because your record did not change. Only the answer at the end of the chain did.

OAuth redirect allowlists

A redirect allowlist is a list of domains authorised to receive authorization codes. It is written once, during integration, and then it is never read again by a human.

A retired partner integration, a decommissioned staging domain, an old mobile deep-link host — each remains a valid destination for a code until someone removes it. Re-registration turns a stale entry into a live account-takeover path.

Webhook targets

Webhooks push data outward on a schedule nobody watches. The receiving domain belongs to a vendor, a customer, or a system that was retired two reorganisations ago. Delivery failures may be logged, but a webhook to a re-registered domain does not fail. It succeeds, to a new recipient.

Package and documentation metadata

Package manifests carry homepage and repository URLs. Documentation carries example hostnames, support addresses and download links. These are read by tooling and by people who assume the domain still belongs to the project.

This is also where the example-domain problem overlaps: a placeholder that was never owned by anyone is functionally identical to a reference whose owner walked away.

Email addresses on domains you let go

An address on a lapsed domain is worse than a dead address. Password resets, invoices and vendor notifications keep being sent there, and the new owner can accept all of it.

Why re-registration is the whole attack

There is no exploit here. Someone waits for a name to become available and buys it. Drop-catching services exist to do this automatically, at scale, the second a domain is released.

What they acquire is not the domain’s traffic. It is the trust that other systems still place in it: the SPF delegation, the allowlist entry, the webhook subscription, the documented download URL. That trust was granted years ago and never revoked, because revoking it requires knowing it exists.

Auditing your own

Nothing here needs tooling you do not already have.

Enumerate what you reference. Extract every domain from SPF records, OAuth and login redirect allowlists, webhook subscriptions, package manifests, CI configuration and infrastructure-as-code.

Check ownership, not availability. Availability is the wrong question — a re-registered domain is unavailable and hostile at the same time. Compare the current registration date against when you added the reference. A creation date more recent than your integration means the name changed hands after you started trusting it.

# One domain, one public RDAP query
curl -s -H 'accept: application/rdap+json' \
  https://rdap.verisign.com/com/v1/domain/EXAMPLE.COM \
  | jq '.events[] | select(.eventAction=="registration") | .eventDate'

Delete rather than update. Most stale entries do not need a replacement. An allowlist entry for a partner you no longer work with should be gone, not repointed.

Then look at what you own. The same failure mode applies in reverse: a domain of yours that lapses becomes somebody else’s dangling reference, pointed at you. Auto-renew and multi-year registration on anything that appears in a config file anywhere.

The connection to example domains

A placeholder domain in documentation is a dangling reference that was born dangling. It points at a name the author never controlled, in a system that will treat it as real the moment the example is copied.

Both problems have the same fix at the source: use the reserved names, and never let a real one become load-bearing by accident.