Skip to content

Commit

Permalink
Ignore port for loopback redirect URIs (#21293)
Browse files Browse the repository at this point in the history
  • Loading branch information
hickford committed Oct 7, 2022
1 parent 0495544 commit 5eda90a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
13 changes: 13 additions & 0 deletions models/auth/oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/base32"
"encoding/base64"
"fmt"
"net"
"net/url"
"strings"

Expand Down Expand Up @@ -56,6 +57,18 @@ func (app *OAuth2Application) PrimaryRedirectURI() string {

// ContainsRedirectURI checks if redirectURI is allowed for app
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
uri, err := url.Parse(redirectURI)
// ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
if err == nil && uri.Scheme == "http" && uri.Port() != "" {
ip := net.ParseIP(uri.Hostname())
if ip != nil && ip.IsLoopback() {
// strip port
uri.Host = uri.Hostname()
if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) {
return true
}
}
}
return util.IsStringInSlice(redirectURI, app.RedirectURIs, true)
}

Expand Down
20 changes: 20 additions & 0 deletions models/auth/oauth2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
assert.False(t, app.ContainsRedirectURI("d"))
}

func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
app := &OAuth2Application{
RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"},
}

// http loopback uris should ignore port
// https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1:3456/"))
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
assert.True(t, app.ContainsRedirectURI("http://[::1]:3456/"))

// not http
assert.False(t, app.ContainsRedirectURI("https://127.0.0.1:3456/"))
// not loopback
assert.False(t, app.ContainsRedirectURI("http://192.168.0.1:9954/"))
assert.False(t, app.ContainsRedirectURI("http://intranet:3456/"))
// unparseable
assert.False(t, app.ContainsRedirectURI(":"))
}

func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application)
Expand Down

0 comments on commit 5eda90a

Please sign in to comment.