mirror of
https://github.com/golang/go.git
synced 2025-11-08 12:41:02 +00:00
net: verify results from Lookup* are valid domain names
For the methods LookupCNAME, LookupSRV, LookupMX, LookupNS, and LookupAddr check that the returned domain names are in fact valid DNS names using the existing isDomainName function. Thanks to Philipp Jeitner and Haya Shulman from Fraunhofer SIT for reporting this issue. Fixes #46241 Fixes CVE-2021-33195 Change-Id: I47a4f58c031cb752f732e88bbdae7f819f0af4f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/323131 Trust: Roland Shoemaker <roland@golang.org> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org> Reviewed-by: Katie Hockman <katie@golang.org>
This commit is contained in:
parent
8bf5bf5173
commit
cdcd02842d
2 changed files with 255 additions and 13 deletions
|
|
@ -1799,3 +1799,160 @@ func TestPTRandNonPTR(t *testing.T) {
|
|||
t.Errorf("names = %q; want %q", names, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCVE202133195(t *testing.T) {
|
||||
fake := fakeDNSServer{
|
||||
rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
|
||||
r := dnsmessage.Message{
|
||||
Header: dnsmessage.Header{
|
||||
ID: q.Header.ID,
|
||||
Response: true,
|
||||
RCode: dnsmessage.RCodeSuccess,
|
||||
RecursionAvailable: true,
|
||||
},
|
||||
Questions: q.Questions,
|
||||
}
|
||||
switch q.Questions[0].Type {
|
||||
case dnsmessage.TypeCNAME:
|
||||
r.Answers = []dnsmessage.Resource{}
|
||||
case dnsmessage.TypeA: // CNAME lookup uses a A/AAAA as a proxy
|
||||
r.Answers = append(r.Answers,
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
Type: dnsmessage.TypeA,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.AResource{
|
||||
A: TestAddr,
|
||||
},
|
||||
},
|
||||
)
|
||||
case dnsmessage.TypeSRV:
|
||||
n := q.Questions[0].Name
|
||||
if n.String() == "_hdr._tcp.golang.org." {
|
||||
n = dnsmessage.MustNewName("<html>.golang.org.")
|
||||
}
|
||||
r.Answers = append(r.Answers,
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: n,
|
||||
Type: dnsmessage.TypeSRV,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.SRVResource{
|
||||
Target: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
case dnsmessage.TypeMX:
|
||||
r.Answers = append(r.Answers,
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
Type: dnsmessage.TypeMX,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.MXResource{
|
||||
MX: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
case dnsmessage.TypeNS:
|
||||
r.Answers = append(r.Answers,
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
Type: dnsmessage.TypeNS,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.NSResource{
|
||||
NS: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
case dnsmessage.TypePTR:
|
||||
r.Answers = append(r.Answers,
|
||||
dnsmessage.Resource{
|
||||
Header: dnsmessage.ResourceHeader{
|
||||
Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
Type: dnsmessage.TypePTR,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Length: 4,
|
||||
},
|
||||
Body: &dnsmessage.PTRResource{
|
||||
PTR: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
return r, nil
|
||||
},
|
||||
}
|
||||
|
||||
r := Resolver{PreferGo: true, Dial: fake.DialContext}
|
||||
// Change the default resolver to match our manipulated resolver
|
||||
originalDefault := DefaultResolver
|
||||
DefaultResolver = &r
|
||||
defer func() {
|
||||
DefaultResolver = originalDefault
|
||||
}()
|
||||
|
||||
_, err := r.LookupCNAME(context.Background(), "golang.org")
|
||||
if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
_, err = LookupCNAME("golang.org")
|
||||
if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
|
||||
_, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
|
||||
if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
_, _, err = LookupSRV("target", "tcp", "golang.org")
|
||||
if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
|
||||
_, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org")
|
||||
if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
_, _, err = LookupSRV("hdr", "tcp", "golang.org")
|
||||
if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
|
||||
_, err = r.LookupMX(context.Background(), "golang.org")
|
||||
if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
_, err = LookupMX("golang.org")
|
||||
if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupMX returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
|
||||
_, err = r.LookupNS(context.Background(), "golang.org")
|
||||
if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
_, err = LookupNS("golang.org")
|
||||
if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupNS returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
|
||||
_, err = r.LookupAddr(context.Background(), "1.2.3.4")
|
||||
if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
_, err = LookupAddr("1.2.3.4")
|
||||
if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected {
|
||||
t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue