summaryrefslogtreecommitdiff
path: root/dev-lang/go/files/go-1.25.3-ipv6-validation.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dev-lang/go/files/go-1.25.3-ipv6-validation.patch')
-rw-r--r--dev-lang/go/files/go-1.25.3-ipv6-validation.patch86
1 files changed, 86 insertions, 0 deletions
diff --git a/dev-lang/go/files/go-1.25.3-ipv6-validation.patch b/dev-lang/go/files/go-1.25.3-ipv6-validation.patch
new file mode 100644
index 000000000000..4f162b2b09a9
--- /dev/null
+++ b/dev-lang/go/files/go-1.25.3-ipv6-validation.patch
@@ -0,0 +1,86 @@
+From 83449b7e2f261c94ea46842012c0992a3a714ce5 Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker <roland@golang.org>
+Date: Wed, 08 Oct 2025 17:13:12 -0700
+Subject: [PATCH] [release-branch.go1.25] net/url: allow IP-literals with IPv4-mapped IPv6 addresses
+
+The security fix we applied in CL709857 was overly broad. It applied
+rules from RFC 2732, which disallowed IPv4-mapped IPv6 addresses, but
+these were later allowed in RFC 3986, which is the canonical URI syntax
+RFC.
+
+Revert the portion of CL709857 which restricted IPv4-mapped addresses,
+and update the related tests.
+
+Updates #75815
+Fixes #75832
+
+Change-Id: I3192f2275ad5c386f5c15006a6716bdb5282919d
+Reviewed-on: https://go-review.googlesource.com/c/go/+/710375
+LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Reviewed-by: Ethan Lee <ethanalee@google.com>
+Auto-Submit: Roland Shoemaker <roland@golang.org>
+(cherry picked from commit 9db7e30bb42eed9912f5e7e9e3959f3b38879d5b)
+---
+
+diff --git a/src/net/url/url.go b/src/net/url/url.go
+index 40faa7c..1c50e06 100644
+--- a/src/net/url/url.go
++++ b/src/net/url/url.go
+@@ -673,13 +673,13 @@
+
+ // Per RFC 3986, only a host identified by a valid
+ // IPv6 address can be enclosed by square brackets.
+- // This excludes any IPv4 or IPv4-mapped addresses.
++ // This excludes any IPv4, but notably not IPv4-mapped addresses.
+ addr, err := netip.ParseAddr(unescapedHostname)
+ if err != nil {
+ return "", fmt.Errorf("invalid host: %w", err)
+ }
+- if addr.Is4() || addr.Is4In6() {
+- return "", errors.New("invalid IPv6 host")
++ if addr.Is4() {
++ return "", errors.New("invalid IP-literal")
+ }
+ return "[" + unescapedHostname + "]" + unescapedColonPort, nil
+ } else if i := strings.LastIndex(host, ":"); i != -1 {
+diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go
+index 3206558..6084fac 100644
+--- a/src/net/url/url_test.go
++++ b/src/net/url/url_test.go
+@@ -726,7 +726,7 @@
+ {"https://[2001:db8::1]/path", true}, // compressed IPv6 address with path
+ {"https://[fe80::1%25eth0]/path?query=1", true}, // link-local with zone, path, and query
+
+- {"https://[::ffff:192.0.2.1]", false},
++ {"https://[::ffff:192.0.2.1]", true},
+ {"https://[:1] ", false},
+ {"https://[1:2:3:4:5:6:7:8:9]", false},
+ {"https://[1::1::1]", false},
+@@ -1672,16 +1672,17 @@
+ {"cache_object:foo/bar", true},
+ {"cache_object/:foo/bar", false},
+
+- {"http://[192.168.0.1]/", true}, // IPv4 in brackets
+- {"http://[192.168.0.1]:8080/", true}, // IPv4 in brackets with port
+- {"http://[::ffff:192.168.0.1]/", true}, // IPv4-mapped IPv6 in brackets
+- {"http://[::ffff:192.168.0.1]:8080/", true}, // IPv4-mapped IPv6 in brackets with port
+- {"http://[::ffff:c0a8:1]/", true}, // IPv4-mapped IPv6 in brackets (hex)
+- {"http://[not-an-ip]/", true}, // invalid IP string in brackets
+- {"http://[fe80::1%foo]/", true}, // invalid zone format in brackets
+- {"http://[fe80::1", true}, // missing closing bracket
+- {"http://fe80::1]/", true}, // missing opening bracket
+- {"http://[test.com]/", true}, // domain name in brackets
++ {"http://[192.168.0.1]/", true}, // IPv4 in brackets
++ {"http://[192.168.0.1]:8080/", true}, // IPv4 in brackets with port
++ {"http://[::ffff:192.168.0.1]/", false}, // IPv4-mapped IPv6 in brackets
++ {"http://[::ffff:192.168.0.1000]/", true}, // Out of range IPv4-mapped IPv6 in brackets
++ {"http://[::ffff:192.168.0.1]:8080/", false}, // IPv4-mapped IPv6 in brackets with port
++ {"http://[::ffff:c0a8:1]/", false}, // IPv4-mapped IPv6 in brackets (hex)
++ {"http://[not-an-ip]/", true}, // invalid IP string in brackets
++ {"http://[fe80::1%foo]/", true}, // invalid zone format in brackets
++ {"http://[fe80::1", true}, // missing closing bracket
++ {"http://fe80::1]/", true}, // missing opening bracket
++ {"http://[test.com]/", true}, // domain name in brackets
+ }
+ for _, tt := range tests {
+ u, err := Parse(tt.in)