diff options
| author | Ian Alexander <jitsu@google.com> | 2026-01-28 15:29:52 -0500 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-03-05 16:15:25 -0800 |
| commit | d8174a9500d53784594b198f6195d1fae8dfe803 (patch) | |
| tree | 145633c05c1130e5ab5f95468f88d8f437ad733c | |
| parent | 4091800393d254befde3770fd16f51200ebd5a3d (diff) | |
| download | go-d8174a9500d53784594b198f6195d1fae8dfe803.tar.xz | |
[release-branch.go1.25] 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 #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>
| -rw-r--r-- | src/net/url/url.go | 4 | ||||
| -rw-r--r-- | src/net/url/url_test.go | 6 |
2 files changed, 9 insertions, 1 deletions
diff --git a/src/net/url/url.go b/src/net/url/url.go index a0974b1ed1..7386d53875 100644 --- a/src/net/url/url.go +++ b/src/net/url/url.go @@ -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, "]") diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go index 944124d20e..6da6b268fe 100644 --- a/src/net/url/url_test.go +++ b/src/net/url/url_test.go @@ -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) |
