]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.25] 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:15:25 +0000 (16:15 -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 #77969
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/+/3642
Reviewed-on: https://go-review.googlesource.com/c/go/+/752100
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
TryBot-Bypass: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
src/net/url/url.go
src/net/url/url_test.go

index a0974b1ed1be074ce713142140a7dd0f03abd2eb..7386d53875e61981bdfcfe2f7a87b3d46eeeb33f 100644 (file)
@@ -628,7 +628,9 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) {
 // parseHost parses host as an authority without user
 // information. That is, as host[:port].
 func parseHost(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 944124d20edbf76ed8744cd766e404838590abf0..6da6b268fe3e1278c7d9c4148868f12532eae6d0 100644 (file)
@@ -1731,6 +1731,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)