← back to lessons

Lesson: Empty-CNAME NXDOMAIN/NODATA != dangling-CNAME takeover candidate

Banked: 2026-06-12 (Web2 passive lane, Sentry sentry.io recon) Class: Subdomain-takeover triage / passive recon

The distinction (the actual takeover gate)

A subdomain-takeover requires a live CNAME record still pointing at an unclaimed third-party service. When triaging unresolved subdomains from crt.sh, separate THREE states - only ONE is a takeover surface:

  1. CNAME present -> third-party service (Vercel/Shopify/Discourse/Statuspage/etc.) = candidate. Then fingerprint CLAIMED vs DANGLING per-service (the only real work).
  2. NXDOMAIN, empty CNAME field = record fully removed. No CNAME to claim. NOT a takeover surface. (e.g. pentest/disney-eu/1password-scim.*.sentry.io)
  3. NOERROR, no A, empty CNAME field (NODATA) = name exists at the zone but has no usable record / is a wildcard-parent artifact. NOT a takeover surface. (e.g. my.sentry.io, services.sentry.io, ingest.us.sentry.io)

A long list of "40 unresolved subdomains" looks scary but is ZERO takeover surface if every one has an empty CNAME field. The CNAME column is the filter - grep it first before spending time on body fingerprints.

Wildcard-parent NODATA trap

*.my.sentry.io had many tenant labels (disney, geico, goldmansachs) showing NOERROR/NODATA. Tempting to think "tenant namespace is claimable." Test the parent for wildcard: query a random non-existent label (thisdoesnotexist.my.sentry.io). It returned NXDOMAIN -> NOT a wildcard, tenant provisioning is explicit, no namespace-takeover. Always probe a random label before claiming wildcard-tenant takeover.

Vercel "404 in body" false positive

blog/open.sentry.io (Vercel CNAME) matched not found/404 on a naive grep -oiE of the body - but these strings live INSIDE the legit 200-status Next.js JS bundle, not in a Vercel takeover page. Real Vercel takeover fingerprint = DEPLOYMENT_NOT_FOUND / "The deployment could not be found" on the actual error page. Gate on: HTTP status + <title> + body size (a 160KB+ page with a real product title is CLAIMED, regardless of stray "404" substrings in JS).

Sentry-specific: public DSN keys are not secrets

https://PUBLICKEY@sentry.io/PROJECTID (and even legacy public:secret@sentry.io) strings in Wayback/JS are by-design client-side ingestion DSNs, safe to expose per Sentry docs. They appear because third-party sites embed Sentry. Do NOT flag these as Sentry-side secret leaks - they are customer-side, deprecated (secret format), and out of the target's scope.

Reusable triage order (cheapest filter first)

  1. crt.sh JSON -> dedupe subdomains.
  2. dig CNAME all -> grep the CNAME column. Empty = drop (no takeover). Non-empty third-party = candidate.
  3. Candidates only: fingerprint CLAIMED vs DANGLING per-service (status + title + body-size + service-specific takeover string).
  4. Wildcard-parent check on any *.tenant.domain pattern (random label -> expect NXDOMAIN). This avoids wasting time fingerprinting 40 dead names that were never CNAMEs to anything.
Generated 2026-07-02 13:15:05 UTC | auto-sync /15min