aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Alexander <jitsu@google.com>2026-01-28 15:29:52 -0500
committerGopher Robot <gobot@golang.org>2026-03-05 16:12:45 -0800
commit65c7d7a9fb3a9d1fbf1e702a211b8cc3a7bedb53 (patch)
tree7822b025adf273b3e36fbdedf494c1b2ce74ccea
parente28ac674af90b079a7018ce8275885b3b5366d2a (diff)
downloadgo-65c7d7a9fb3a9d1fbf1e702a211b8cc3a7bedb53.tar.xz
[release-branch.go1.26] net/url: reject IPv6 literal not at start of host
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>
-rw-r--r--src/net/url/url.go4
-rw-r--r--src/net/url/url_test.go6
2 files changed, 9 insertions, 1 deletions
diff --git a/src/net/url/url.go b/src/net/url/url.go
index 202957a3a2..36d1820084 100644
--- a/src/net/url/url.go
+++ b/src/net/url/url.go
@@ -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, "]")
diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go
index d099353eb2..f0f3f97800 100644
--- a/src/net/url/url_test.go
+++ b/src/net/url/url_test.go
@@ -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)