Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: mishandling of dotted labels in domain names #10631

Closed
mdempsky opened this issue Apr 30, 2015 · 5 comments
Closed

net: mishandling of dotted labels in domain names #10631

mdempsky opened this issue Apr 30, 2015 · 5 comments
Milestone

Comments

@mdempsky
Copy link
Member

The DNS master zone and wire formats in RFC 1035 allow arbitrary binary strings within labels. This is explicitly reaffirmed in section 11 of RFC 2181: "Those [length] restrictions aside, any binary string whatever can be used as the label of any resource record. [...] Implementations of the DNS protocols must not place any restrictions on the labels that can be used."

However, currently the Go DNS resolver decodes DNS wire format domain names into dotted notation without accounting for dots within a label. For example, "dig" correctly resolves the following CNAME chain:

$ dig -t txt go.cname-bug.dempsky.org.
[...]
;; ANSWER SECTION:
go.cname-bug.dempsky.org. 300   IN      CNAME   foo\.bar.cname-bug.dempsky.org.
foo\.bar.cname-bug.dempsky.org. 300 IN  CNAME   foo.bar.cname-bug.dempsky.org.
foo.bar.cname-bug.dempsky.org. 300 IN   TXT     "ok"

But this Go program:

package main
import (
        "fmt"
        "net"
)
func main() {
        fmt.Println(net.LookupTXT("go.cname-bug.dempsky.org."))
}

fails on Linux with the output:

[] lookup foo.bar.cname-bug.dempsky.org. on 127.0.1.1:53: too many redirects

(I'm curious what it outputs on Windows and/or Plan 9, since Go uses the native OS resolver library on those platforms.)

Fixing net.LookupTXT would be relatively easy, but it's less clear what the other net.LookupFoo methods should return if they would need to return a dotted label to the caller.

For comparison, the BIND DNS client library's ns_name_ntop function uses RFC 1035 escaping: the "special" characters ".;\()@$ are escaped with a \, other "printable" characters (>0x20 && <0x7f) are encoded directly, and anything else uses a \ddd decimal escape sequence. (Decimal escapes aren't universal though; at least djbdns and AWS Route 53 use octal escapes instead.)

In issue #1167, @rsc interpreted RFC 2181 as saying "clients can impose whatever restrictions they choose"** to justify disallowing querying arbitrary domain names. Taking that as precedent, it could instead be appropriate to make these functions return a similar "invalid domain name" DNSError if a dotted label is discovered. And relevantly, the BIND DNS client library returns "host not found" errors if during host name resolution it finds a CNAME record that points to a non-host-name. E.g., running host gai.cname-bug.dempsky.org. succeeds, but using getaddrinfo on that name will fail, because _gai.cname-bug.dempsky.org is not a valid host name.

** Though I think that's a misinterpretation of "Clients of the DNS can impose whatever restrictions are appropriate to their circumstances on the values they use as keys for DNS lookup requests, and on the values returned by the DNS." I believe it's actually referring to how specific applications of DNS such as host name resolution might apply the stricter host name requirements from RFC 1123, even though domain names are more general. Notably, LookupHost and LookupIP are documented as resolving "host"s, whereas LookupMX, LookupNS, LookupSRV, and LookupTXT resolve "domain name"s.

@mikioh mikioh added this to the Go1.5Maybe milestone May 2, 2015
@nightlyone
Copy link
Contributor

Do you have any interesting real world use cases that fail at the moment?

@rsc
Copy link
Contributor

rsc commented Jul 15, 2015

Does this ever come up in real life?

It's an interesting boundary case, but it's hard to believe we need to worry about it.

@mdempsky
Copy link
Member Author

mdempsky commented Dec 4, 2019

Ran into this writing a fuzzer for x/net/dns/dnsmessage, which exposes pack and unpack methods for DNS messages. In particular, a name like "\.z" (i.e., wire encoding "\x02.z\x00") gets decoded as ".z", which then fails to re-encode because of a zero-length segment.

To answer the past questions: I don't know of any evidence of it affecting real world applications. I think it would be reasonable to explicitly error when parsing packets that contain dots within labels. I think it's risky to mis-parse the packets though.

@mateusz834
Copy link
Member

This is now fixed (#56246). Dots inside labels are rejected.

@ianlancetaylor
Copy link
Contributor

@mateusz834 Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants