From b89c757817413d75edb2e687bddde8e94a76a956 Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Fri, 26 Feb 2021 11:16:12 -0500 Subject: [PATCH] wgengine/tsdns: explicitly reject .onion lookups Tor has a location-hidden service feature that enables users to host services from inside the Tor network. Each of these gets a unique DNS name that ends with .onion. As it stands now, if a misbehaving application somehow manages to make a .onion DNS request to our DNS server, we will forward that to the DNS server, which could leak that to malicious third parties. See the recent bug Brave had with this[1] for more context. RFC 7686 suggests that name resolution APIs and libraries MUST respond with NXDOMAIN unless they can actually handle Tor lookups. We can't handle .onion lookups, so we reject them. [1]: https://twitter.com/albinowax/status/1362737949872431108 Fixes tailscale/corp#1351 Signed-off-by: Christine Dodrill --- wgengine/tsdns/tsdns.go | 5 +++++ wgengine/tsdns/tsdns_test.go | 1 + 2 files changed, 6 insertions(+) diff --git a/wgengine/tsdns/tsdns.go b/wgengine/tsdns/tsdns.go index 680bf51b3..23db7bba4 100644 --- a/wgengine/tsdns/tsdns.go +++ b/wgengine/tsdns/tsdns.go @@ -194,6 +194,11 @@ func (r *Resolver) Resolve(domain string, tp dns.Type) (netaddr.IP, dns.RCode, e return netaddr.IP{}, dns.RCodeServerFailure, errMapNotSet } + // Reject .onion domains per RFC 7686. + if dnsname.HasSuffix(domain, ".onion") { + return netaddr.IP{}, dns.RCodeNameError, nil + } + anyHasSuffix := false for _, suffix := range dnsMap.rootDomains { if dnsname.HasSuffix(domain, suffix) { diff --git a/wgengine/tsdns/tsdns_test.go b/wgengine/tsdns/tsdns_test.go index a2f56a168..66a62d107 100644 --- a/wgengine/tsdns/tsdns_test.go +++ b/wgengine/tsdns/tsdns_test.go @@ -219,6 +219,7 @@ func TestResolve(t *testing.T) { {"mx-ipv6", "test2.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeSuccess}, {"mx-nxdomain", "test3.ipn.dev.", dns.TypeMX, netaddr.IP{}, dns.RCodeNameError}, {"ns-nxdomain", "test3.ipn.dev.", dns.TypeNS, netaddr.IP{}, dns.RCodeNameError}, + {"onion-domain", "footest.onion.", dns.TypeA, netaddr.IP{}, dns.RCodeNameError}, } for _, tt := range tests {