Skip to content

Commit 679e749

Browse files
committed
net/url: don't permit a colon after the port
Fixes #75223 Change-Id: Iaa12c7fc227ff33b8e97926d10967994a781720d
1 parent 4c4cefc commit 679e749

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/net/url/url.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,14 @@ func parseHost(host string) (string, error) {
661661
return host1 + host2 + host3, nil
662662
}
663663
} else if i := strings.LastIndex(host, ":"); i != -1 {
664+
if j := strings.LastIndex(host[:i], ":"); j != -1 { // multiple colons
665+
if k := strings.LastIndex(host[:j], ":"); k == -1 { // only one other colon
666+
if port := host[j+1 : i]; validPort(port) { // see issue #75223
667+
return "", fmt.Errorf("a colon after port %q is not allowed", port)
668+
}
669+
}
670+
}
671+
664672
colonPort := host[i:]
665673
if !validOptionalPort(colonPort) {
666674
return "", fmt.Errorf("invalid port %q after host", colonPort)
@@ -801,7 +809,11 @@ func validOptionalPort(port string) bool {
801809
if port[0] != ':' {
802810
return false
803811
}
804-
for _, b := range port[1:] {
812+
return validPort(port[1:])
813+
}
814+
815+
func validPort(port string) bool {
816+
for _, b := range port {
805817
if b < '0' || b > '9' {
806818
return false
807819
}

src/net/url/url_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,13 @@ var parseRequestURLTests = []struct {
707707
// RFC 6874.
708708
{"http://[fe80::1%en0]/", false},
709709
{"http://[fe80::1%en0]:8080/", false},
710+
711+
{"http://x:x:", true}, // malformed IPv6 but still accepted
712+
{"http://x::", false}, // a colon after empty port is not allowed
713+
{"http://x:1:", false}, // a colon after the port is not allowed
714+
{"http://x:12:", false}, // a colon after the port is not allowed
715+
{"http://x:123:", false}, // a colon after the port is not allowed
716+
{"http://127.0.0.1:8080:", false}, // a colon after the port is not allowed
710717
}
711718

712719
func TestParseRequestURI(t *testing.T) {
@@ -1643,6 +1650,13 @@ func TestParseErrors(t *testing.T) {
16431650
{"cache_object:foo", true},
16441651
{"cache_object:foo/bar", true},
16451652
{"cache_object/:foo/bar", false},
1653+
1654+
{"http://x:x:", false}, // malformed IPv6 but still accepted
1655+
{"http://x::", true}, // a colon after empty port is not allowed
1656+
{"http://x:1:", true}, // a colon after the port is not allowed
1657+
{"http://x:12:", true}, // a colon after the port is not allowed
1658+
{"http://x:123:", true}, // a colon after the port is not allowed
1659+
{"http://127.0.0.1:8080:", true}, // a colon after the port is not allowed
16461660
}
16471661
for _, tt := range tests {
16481662
u, err := Parse(tt.in)

0 commit comments

Comments
 (0)