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 <xe@tailscale.com>
This commit is contained in:
Christine Dodrill 2021-02-26 11:16:12 -05:00 committed by Brad Fitzpatrick
parent c0cdca6d06
commit b89c757817
2 changed files with 6 additions and 0 deletions

View File

@ -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) {

View File

@ -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 {