diff --git a/CHANGELOG.md b/CHANGELOG.md index 19703bcbe3..f17e3136f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ - [#2755](https://github.com/oauth2-proxy/oauth2-proxy/pull/2755) feat: add X-Envoy-External-Address as supported header (@bjencks) - [#1985](https://github.com/oauth2-proxy/oauth2-proxy/pull/1985) Add support for systemd socket (@isodude) - [#2300](https://github.com/oauth2-proxy/oauth2-proxy/pull/2300) Add fix for websocket path rewrite (@rekup) -- [#2821](https://github.com/oauth2-proxy/oauth2-proxy/pull/2821) feat: add CF-Connecting-IP as supported real ip header +- [#2821](https://github.com/oauth2-proxy/oauth2-proxy/pull/2821) feat: add CF-Connecting-IP as supported real ip header (@ondrejsika) +- [#2620](https://github.com/oauth2-proxy/oauth2-proxy/pull/2620) fix: update code_verifier to use recommended method (@vishvananda) # V7.7.1 diff --git a/oauthproxy.go b/oauthproxy.go index cc2a5ee62c..ca9d4e975e 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -802,7 +802,7 @@ func (p *OAuthProxy) doOAuthStart(rw http.ResponseWriter, req *http.Request, ove ) if p.provider.Data().CodeChallengeMethod != "" { codeChallengeMethod = p.provider.Data().CodeChallengeMethod - codeVerifier, err = encryption.GenerateRandomASCIIString(96) + codeVerifier, err = encryption.GenerateCodeVerifierString(96) if err != nil { logger.Errorf("Unable to build random ASCII string for code verifier: %v", err) p.ErrorPage(rw, req, http.StatusInternalServerError, err.Error()) diff --git a/pkg/encryption/utils.go b/pkg/encryption/utils.go index 426a313111..df0158b88c 100644 --- a/pkg/encryption/utils.go +++ b/pkg/encryption/utils.go @@ -7,7 +7,7 @@ import ( "encoding/base64" "fmt" "hash" - "math/big" + "io" "net/http" "strconv" "strings" @@ -83,17 +83,13 @@ func SignedValue(seed string, key string, value []byte, now time.Time) (string, return cookieVal, nil } -func GenerateRandomASCIIString(length int) (string, error) { - b := make([]byte, length) - charsetLen := new(big.Int).SetInt64(int64(len(asciiCharset))) - for i := range b { - character, err := rand.Int(rand.Reader, charsetLen) - if err != nil { - return "", err - } - b[i] = asciiCharset[character.Int64()] +// GenerateCodeVerifierString returns a base64 encoded string of n random bytes +func GenerateCodeVerifierString(n int) (string, error) { + data := make([]byte, n) + if _, err := io.ReadFull(rand.Reader, data); err != nil { + return "", err } - return string(b), nil + return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(data), nil } func GenerateCodeChallenge(method, codeVerifier string) (string, error) { diff --git a/pkg/encryption/utils_test.go b/pkg/encryption/utils_test.go index 9e69df842a..0f4320e025 100644 --- a/pkg/encryption/utils_test.go +++ b/pkg/encryption/utils_test.go @@ -130,12 +130,12 @@ func TestValidate(t *testing.T) { assert.Equal(t, validValue, expectedValue) } -func TestGenerateRandomASCIIString(t *testing.T) { - randomString, err := GenerateRandomASCIIString(96) +func TestGenerateCodeVerifierString(t *testing.T) { + randomString, err := GenerateCodeVerifierString(96) assert.NoError(t, err) - // Only 8-bit characters - assert.Equal(t, 96, len([]byte(randomString))) + // Should be 128 characters long + assert.Equal(t, 128, len([]byte(randomString))) // All non-ascii characters removed should still be the original string removedChars := strings.Map(func(r rune) rune {