]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.26] net/url: reject IPv6 literal not at start of host
authorIan Alexander <jitsu@google.com>
Wed, 28 Jan 2026 20:29:52 +0000 (15:29 -0500)
committerGopher Robot <gobot@golang.org>
Fri, 6 Mar 2026 00:12:45 +0000 (16:12 -0800)
This change rejects IPv6 literals that do not appear at the start of the
host subcomponent of a URL.

For example:
  http://example.com[::1] -> rejects
  http://[::1]            -> accepts

Thanks to Masaki Hara (https://github.com/qnighy) of Wantedly.

Updates #77578
Fixes #77970
Fixes CVE-2026-25679

Change-Id: I7109031880758f7c1eb4eca513323328feace33c
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3400
Reviewed-by: Neal Patel <nealpatel@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3622
Reviewed-on: https://go-review.googlesource.com/c/go/+/752080
Auto-Submit: Gopher Robot <gobot@golang.org>
TryBot-Bypass: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/net/url/url.go
src/net/url/url_test.go

index 202957a3a2d8bc4c2509a60dd58a096f0521375b..36d182008454587f1a58b81b0acd5735adaacd36 100644 (file)
@@ -547,7 +547,9 @@ func parseAuthority(scheme, authority string) (user *Userinfo, host string, err
 // parseHost parses host as an authority without user
 // information. That is, as host[:port].
 func parseHost(scheme, host string) (string, error) {
-       if openBracketIdx := strings.LastIndex(host, "["); openBracketIdx != -1 {
+       if openBracketIdx := strings.LastIndex(host, "["); openBracketIdx > 0 {
+               return "", errors.New("invalid IP-literal")
+       } else if openBracketIdx == 0 {
                // Parse an IP-Literal in RFC 3986 and RFC 6874.
                // E.g., "[fe80::1]", "[fe80::1%25en0]", "[fe80::1]:80".
                closeBracketIdx := strings.LastIndex(host, "]")
index d099353eb2618cce57e13c7ce8140471ba8ec187..f0f3f978005b0e36f7ef4b18b41106a57c7bc50d 100644 (file)
@@ -1756,6 +1756,12 @@ func TestParseErrors(t *testing.T) {
                {"http://[fe80::1", true},                    // missing closing bracket
                {"http://fe80::1]/", true},                   // missing opening bracket
                {"http://[test.com]/", true},                 // domain name in brackets
+               {"http://example.com[::1]", true},            // IPv6 literal doesn't start with '['
+               {"http://example.com[::1", true},
+               {"http://[::1", true},
+               {"http://.[::1]", true},
+               {"http:// [::1]", true},
+               {"hxxp://mathepqo[.]serveftp(.)com:9059", true},
        }
        for _, tt := range tests {
                u, err := Parse(tt.in)