# checker-dangling A happyDomain checker that scans a working zone for **dangling subdomains**: records (`CNAME` / `MX` / `SRV` / `NS`) whose targets resolve to NXDOMAIN, or whose external registrable domain is expired, in `pendingDelete`, or recently re-registered. This is the attack class popularised by Ars Technica in 2017, where universities ended up serving porn from CNAMEs that pointed at decommissioned third-party services after malicious actors re-registered the lapsed targets. It runs in three deployment modes (standalone HTTP binary, Go plugin, Docker image), like every other checker in the happyDomain ecosystem. ## How it works The checker walks every service in the working zone (`AutoFillZone`) and extracts pointer records from `svcs.CNAME`, `svcs.SpecialCNAME`, `svcs.MXs`, `svcs.UnknownSRV`, and `svcs.Orphan` bodies (the latter covering bare `NS`/`CNAME`/`MX` records when no dedicated service is attached). For each (owner, rrtype, target) triple it: 1. Classifies the target as in-zone or external relative to the zone's eTLD+1 (via `golang.org/x/net/publicsuffix`). 2. Performs a single, time-bounded DNS resolution to detect immediate breakage (`nxdomain`, `servfail`, `no_answer`, `timeout`). 3. Publishes a `DiscoveryEntry` per pointer: - `dangling.external-target.v1` for external pointers — companion checkers (notably the host's `domain_expiry`) subscribe to this type and run RDAP/WHOIS on the registrable domain. - `dangling.in-zone-target.v1` for same-registrable pointers — used as a join key for future reachability checkers (alias / ping / http) that may consume it. ## Verdict matrix | Signal | Severity | Source | |--------------------------------------------------------------|----------|-------------------------| | Target NXDOMAIN | Critical | local DNS resolution | | Target SERVFAIL | Warning | local DNS resolution | | Target NOERROR with empty answer | Info | local DNS resolution | | Registrable domain expired | Critical | `whois` related obs. | | Registrable status `pendingDelete` / `redemptionPeriod` | Critical | `whois` related obs. | | Registrable registered within the last 90 days | Warning | `whois` related obs. | The rule emits one `CheckState` per impacted owner and ranks them by descending severity so the report's "Fix this first" card always matches the rule output. ## Companion: `domain_expiry` For the WHOIS-driven signals to fire, the host's existing `domain_expiry` checker must be extended to subscribe to `dangling.external-target.v1` entries via `AutoFillDiscoveryEntries`, run RDAP per registrable domain, and publish a per-Ref `whois` observation. Without that subscription the checker still works as a DNS-only dangling detector. ## Build ```sh make # standalone binary make plugin # .so plugin for happyDomain make docker # Docker image make test # run the unit tests ```