From 1f27af44d4f83c258c118839ca3171fff08aa77b Mon Sep 17 00:00:00 2001 From: Mitar Date: Thu, 15 Feb 2024 02:00:27 -0800 Subject: [PATCH] fix: use stdlib to check loopback address (#795) --- authorize_helper.go | 17 ++++++----------- authorize_helper_whitebox_test.go | 23 ++++++++++++++++++----- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/authorize_helper.go b/authorize_helper.go index 4514a4aa..0b98cfe9 100644 --- a/authorize_helper.go +++ b/authorize_helper.go @@ -8,8 +8,8 @@ import ( "fmt" "html/template" "io" + "net" "net/url" - "regexp" "strings" "github.com/ory/x/errorsx" @@ -130,7 +130,7 @@ func isMatchingAsLoopback(requested *url.URL, registeredURI string) bool { // // Source: https://tools.ietf.org/html/rfc8252#section-7.3 if requested.Scheme == "http" && - isLoopbackAddress(requested.Host) && + isLoopbackAddress(requested.Hostname()) && registered.Hostname() == requested.Hostname() && // The port is skipped here - see codedoc above! registered.Path == requested.Path && @@ -141,14 +141,9 @@ func isMatchingAsLoopback(requested *url.URL, registeredURI string) bool { return false } -var ( - regexLoopbackAddress = regexp.MustCompile(`^(127\.0\.0\.1|\[::1])(:\d+)?$`) -) - -// Check if address is either an IPv4 loopback or an IPv6 loopback- -// An optional port is ignored -func isLoopbackAddress(address string) bool { - return regexLoopbackAddress.MatchString(address) +// Check if address is either an IPv4 loopback or an IPv6 loopback. +func isLoopbackAddress(hostname string) bool { + return net.ParseIP(hostname).IsLoopback() } // IsValidRedirectURI validates a redirect_uri as specified in: @@ -186,7 +181,7 @@ func IsRedirectURISecureStrict(ctx context.Context, redirectURI *url.URL) bool { func IsLocalhost(redirectURI *url.URL) bool { hn := redirectURI.Hostname() - return strings.HasSuffix(hn, ".localhost") || hn == "127.0.0.1" || hn == "::1" || hn == "localhost" + return strings.HasSuffix(hn, ".localhost") || isLoopbackAddress(hn) || hn == "localhost" } func WriteAuthorizeFormPostResponse(redirectURL string, parameters url.Values, template *template.Template, rw io.Writer) { diff --git a/authorize_helper_whitebox_test.go b/authorize_helper_whitebox_test.go index 39ed6070..e4d6eb13 100644 --- a/authorize_helper_whitebox_test.go +++ b/authorize_helper_whitebox_test.go @@ -4,6 +4,7 @@ package fosite import ( + "net/url" "testing" "github.com/stretchr/testify/assert" @@ -34,14 +35,25 @@ func TestIsLookbackAddress(t *testing.T) { "ShouldReturnTrueIPv6LoopbackWithPort", "[::1]:1230", true, - }, { - "ShouldReturnFalse12700255", + }, + { + "ShouldReturnTrue12700255", "127.0.0.255", - false, + true, }, { - "ShouldReturnFalse12700255WithPort", + "ShouldReturnTrue12700255WithPort", "127.0.0.255:1230", + true, + }, + { + "ShouldReturnFalse128001", + "128.0.0.1", + false, + }, + { + "ShouldReturnFalse128001WithPort", + "128.0.0.1:1230", false, }, { @@ -63,7 +75,8 @@ func TestIsLookbackAddress(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - assert.Equal(t, tc.expected, isLoopbackAddress(tc.have)) + u := url.URL{Host: tc.have} + assert.Equal(t, tc.expected, isLoopbackAddress(u.Hostname())) }) } }