Skip to content

Commit fdb8413

Browse files
rolandshoemakergopherbot
authored andcommitted
[release-branch.go1.23] crypto/x509: properly check for IPv6 hosts in URIs
When checking URI constraints, use netip.ParseAddr, which understands zones, unlike net.ParseIP which chokes on them. This prevents zone IDs from mistakenly satisfying URI constraints. Thanks to Juho Forsén of Mattermost for reporting this issue. For #71156 Fixes #71208 Fixes CVE-2024-45341 Change-Id: Iecac2529f3605382d257996e0fb6d6983547e400 Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1700 Reviewed-by: Tatiana Bradley <[email protected]> Reviewed-by: Damien Neil <[email protected]> (cherry picked from commit 22ca55d396ba801e6ae9b2bd67a059fcb30562fd) Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1762 Reviewed-by: Roland Shoemaker <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/go/+/643103 LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Michael Knyszek <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent 1dde0b4 commit fdb8413

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/crypto/x509/name_constraints_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,23 @@ var nameConstraintsTests = []nameConstraintsTest{
16071607
leaf: leafSpec{sans: []string{"dns:.example.com"}},
16081608
expectedError: "cannot parse dnsName \".example.com\"",
16091609
},
1610+
// #86: URIs with IPv6 addresses with zones and ports are rejected
1611+
{
1612+
roots: []constraintsSpec{
1613+
{
1614+
ok: []string{"uri:example.com"},
1615+
},
1616+
},
1617+
intermediates: [][]constraintsSpec{
1618+
{
1619+
{},
1620+
},
1621+
},
1622+
leaf: leafSpec{
1623+
sans: []string{"uri:http://[2006:abcd::1%25.example.com]:16/"},
1624+
},
1625+
expectedError: "URI with IP",
1626+
},
16101627
}
16111628

16121629
func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {

src/crypto/x509/verify.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"errors"
1212
"fmt"
1313
"net"
14+
"net/netip"
1415
"net/url"
1516
"reflect"
1617
"runtime"
@@ -434,8 +435,10 @@ func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
434435
}
435436
}
436437

437-
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") ||
438-
net.ParseIP(host) != nil {
438+
// netip.ParseAddr will reject the URI IPv6 literal form "[...]", so we
439+
// check if _either_ the string parses as an IP, or if it is enclosed in
440+
// square brackets.
441+
if _, err := netip.ParseAddr(host); err == nil || (strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]")) {
439442
return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
440443
}
441444

0 commit comments

Comments
 (0)