From 7953dfc3ed862aad38269fe3f0dee53d661a85cc Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 3 Jun 2026 23:06:10 +0900 Subject: [PATCH] analyzer: strip resolver address from DNS lookup error messages Wrap user-facing lookup errors through a new formatDNSError helper that clears net.DNSError.Server so the " on " suffix no longer leaks the upstream resolver (e.g. "on 127.0.0.11:53") to end users. Closes: https://framagit.org/happyDomain/happydeliver/-/work_items/2 --- pkg/analyzer/dns_bimi.go | 2 +- pkg/analyzer/dns_dkim.go | 2 +- pkg/analyzer/dns_dmarc.go | 2 +- pkg/analyzer/dns_mx.go | 2 +- pkg/analyzer/dns_resolver.go | 13 +++++++++++++ pkg/analyzer/dns_spf.go | 2 +- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/pkg/analyzer/dns_bimi.go b/pkg/analyzer/dns_bimi.go index 223bfdc..b037978 100644 --- a/pkg/analyzer/dns_bimi.go +++ b/pkg/analyzer/dns_bimi.go @@ -45,7 +45,7 @@ func (d *DNSAnalyzer) checkBIMIRecord(domain, selector string) *model.BIMIRecord Selector: selector, Domain: domain, Valid: false, - Error: utils.PtrTo(fmt.Sprintf("Failed to lookup BIMI record: %v", err)), + Error: utils.PtrTo(fmt.Sprintf("Failed to lookup BIMI record: %s", formatDNSError(err))), } } diff --git a/pkg/analyzer/dns_dkim.go b/pkg/analyzer/dns_dkim.go index 115e347..5708d1c 100644 --- a/pkg/analyzer/dns_dkim.go +++ b/pkg/analyzer/dns_dkim.go @@ -122,7 +122,7 @@ func (d *DNSAnalyzer) checkDKIMRecord(h DKIMHeader) *model.DKIMRecord { Domain: h.Domain, SigningAlgorithm: signingAlgorithmPtr(h.Algorithm), Valid: false, - Error: utils.PtrTo(fmt.Sprintf("Failed to lookup DKIM record: %v", err)), + Error: utils.PtrTo(fmt.Sprintf("Failed to lookup DKIM record: %s", formatDNSError(err))), } } diff --git a/pkg/analyzer/dns_dmarc.go b/pkg/analyzer/dns_dmarc.go index b89500b..20058b2 100644 --- a/pkg/analyzer/dns_dmarc.go +++ b/pkg/analyzer/dns_dmarc.go @@ -193,7 +193,7 @@ func (d *DNSAnalyzer) checkDMARCRecord(domain string) *model.DMARCRecord { if err != nil { return &model.DMARCRecord{ Valid: false, - Error: utils.PtrTo(fmt.Sprintf("Failed to lookup DMARC record: %v", err)), + Error: utils.PtrTo(fmt.Sprintf("Failed to lookup DMARC record: %s", formatDNSError(err))), } } if foundDomain == "" { diff --git a/pkg/analyzer/dns_mx.go b/pkg/analyzer/dns_mx.go index c48c9a4..51c9eca 100644 --- a/pkg/analyzer/dns_mx.go +++ b/pkg/analyzer/dns_mx.go @@ -39,7 +39,7 @@ func (d *DNSAnalyzer) checkMXRecords(domain string) *[]model.MXRecord { return &[]model.MXRecord{ { Valid: false, - Error: utils.PtrTo(fmt.Sprintf("Failed to lookup MX records: %v", err)), + Error: utils.PtrTo(fmt.Sprintf("Failed to lookup MX records: %s", formatDNSError(err))), }, } } diff --git a/pkg/analyzer/dns_resolver.go b/pkg/analyzer/dns_resolver.go index f60484f..266078e 100644 --- a/pkg/analyzer/dns_resolver.go +++ b/pkg/analyzer/dns_resolver.go @@ -23,9 +23,22 @@ package analyzer import ( "context" + "errors" "net" ) +// formatDNSError renders a resolution error without exposing the upstream +// resolver address that net.DNSError.Error() normally appends as " on ". +func formatDNSError(err error) string { + var dnsErr *net.DNSError + if errors.As(err, &dnsErr) { + sanitized := *dnsErr + sanitized.Server = "" + return sanitized.Error() + } + return err.Error() +} + // DNSResolver defines the interface for DNS resolution operations. // This interface abstracts DNS lookups to allow for custom implementations, // such as mock resolvers for testing or caching resolvers for performance. diff --git a/pkg/analyzer/dns_spf.go b/pkg/analyzer/dns_spf.go index ccb1674..5628986 100644 --- a/pkg/analyzer/dns_spf.go +++ b/pkg/analyzer/dns_spf.go @@ -67,7 +67,7 @@ func (d *DNSAnalyzer) resolveSPFRecords(domain string, visited map[string]bool, { Domain: &domain, Valid: false, - Error: utils.PtrTo(fmt.Sprintf("Failed to lookup TXT records: %v", err)), + Error: utils.PtrTo(fmt.Sprintf("Failed to lookup TXT records: %s", formatDNSError(err))), }, } }