Skip to content

Security

Security

Reporting

Report vulnerabilities through GitHub Private Vulnerability Reporting on the repository (the Security tab → Report a vulnerability). Please do not open a public issue for a suspected vulnerability. This is a best-effort project — there is no security@ mailbox, PGP key, response SLA, or CVE pipeline; GitHub's advisory workflow is the single supported channel. The full policy is in the repository's SECURITY.md.

What this library defends

The security-sensitive design decisions, and where each is documented:

Authoritative reads over cached reads

Domain verification and propagation read from a zone's authoritative nameservers, not a recursive cache. A recursive cache can be stale or, on a shared resolver, poisoned — so trusting it for an ownership decision is unsafe. Verification is deny-by-default: any failure or non-exact match is false, and the token compare is constant-time (hash_equals).

Response-spoofing resistance

The socket resolver accepts a UDP answer only when its transaction ID and echoed question (name + type) match the query; a mismatch is rejected as malformed rather than trusted. Optional 0x20 mixed-case encoding adds further entropy where the server preserves case. This is what makes a direct authoritative read trustworthy against off-path spoofing.

SSRF-safe nameserver discovery

A domain owner controls their own NS and glue records, so the authoritative resolver treats NS-derived addresses as untrusted: by default it queries only globally-routable public IPs (RFC1918, loopback, link-local/metadata, and other reserved space are refused) and caps the NS fan-out. allowNonPublicNameservers opts into LAN/internal servers when you deliberately want to check one. Nameserver IPs you pass explicitly are never filtered — only ones discovered from DNS.

DNSSEC validation, deny-by-default

The DNSSEC module validates the chain itself rather than trusting a resolver's AD bit. Anything not provably Secure or provably Insecure is Bogus: unknown algorithm, tampered or expired signature, broken DS link, out-of-bailiwick signer, unproven wildcard — all rejected. See the full threat model and the deny-by-default matrix.

Key posture points:

  • Signature math is delegated to OpenSSL (RSA/ECDSA) and libsodium (Ed25519) — never hand-rolled.
  • Algorithms are pinned to an allow-list; an unrecognised algorithm is a failure, closing off algorithm-confusion.
  • The chain is anchored on the IANA root KSK DS records held in-code; trust comes from the cryptography, not the transport.
  • Signers are in-bailiwick enforced — a validly-signed zone cannot forge another zone's records. This closes a cross-zone forgery bypass found during pre-release adversarial review.

Testing and review — honest scope

The DNSSEC module is tested against real captured signed-zone vectors and self-signed test chains, and was adversarially security-reviewed before release. It has not had a formal third-party audit, and the package makes no conformance-certification claim. Treat it as carefully-engineered, not certified.

Out of scope

This is a DNS-only library. It does not perform live SMTP probing, RBL/blacklist lookups, or geo-distributed measurement — see the diagnostics scope. It reads DNS; it does not manage zones, write records, or act as a resolver daemon.