From 551b6c90563b1571137d21b759fda67ecea50309 Mon Sep 17 00:00:00 2001 From: Tim White Date: Mon, 20 Nov 2023 17:36:03 +0800 Subject: [PATCH] Support http.AllowQuerySemicolons (#2248) * Support http.AllowQuerySemicolons * Docs * Make it clear we are overriding the handler * Update documentation for allow-query-semicolons * Fix changelog format * Fix formatting --------- Co-authored-by: MickMake --- CHANGELOG.md | 2 +- docs/docs/configuration/overview.md | 1 + oauthproxy.go | 67 ++++++++++++++++------------- pkg/apis/options/options.go | 2 + 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93e40a37..ebbb37c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,6 @@ ## Breaking Changes ## Changes since v7.5.1 - - [#2128](https://github.com/oauth2-proxy/oauth2-proxy/pull/2128) Update dependencies (@vllvll) - [#2269](https://github.com/oauth2-proxy/oauth2-proxy/pull/2269) Added Azure China (and other air gaped cloud) support (@mblaschke) - [#2237](https://github.com/oauth2-proxy/oauth2-proxy/pull/2237) adds an option to append CA certificates (@emsixteeen) @@ -19,6 +18,7 @@ - [#1866](https://github.com/oauth2-proxy/oauth2-proxy/pull/1866) Add support for unix socker as upstream (@babs) - [#1949](https://github.com/oauth2-proxy/oauth2-proxy/pull/1949) Allow cookie names with dots in redis sessions (@miguelborges99) - [#2297](https://github.com/oauth2-proxy/oauth2-proxy/pull/2297) Add nightly build and push (@tuunit) +- [#2248](https://github.com/oauth2-proxy/oauth2-proxy/pull/2248) Added support for semicolons in query strings. # V7.5.1 diff --git a/docs/docs/configuration/overview.md b/docs/docs/configuration/overview.md index 11d2fc8f..544b2bf5 100644 --- a/docs/docs/configuration/overview.md +++ b/docs/docs/configuration/overview.md @@ -67,6 +67,7 @@ An example [oauth2-proxy.cfg](https://github.com/oauth2-proxy/oauth2-proxy/blob/ | Option | Type | Description | Default | | ------ | ---- | ----------- | ------- | | `--acr-values` | string | optional, see [docs](https://openid.net/specs/openid-connect-eap-acr-values-1_0.html#acrValues) | `""` | +| `--allow-query-semicolons` | bool | allow the use of semicolons in query args ([required for some legacy applications](https://github.com/golang/go/issues/25192)) | `false` | | `--api-route` | string \| list | return HTTP 401 instead of redirecting to authentication server if token is not valid. Format: path_regex | | | `--approval-prompt` | string | OAuth approval_prompt | `"force"` | | `--auth-logging` | bool | Log authentication attempts | true | diff --git a/oauthproxy.go b/oauthproxy.go index c4b0d51b..40a622eb 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -83,22 +83,23 @@ type OAuthProxy struct { SignInPath string - allowedRoutes []allowedRoute - apiRoutes []apiRoute - redirectURL *url.URL // the url to receive requests at - relativeRedirectURL bool - whitelistDomains []string - provider providers.Provider - sessionStore sessionsapi.SessionStore - ProxyPrefix string - basicAuthValidator basic.Validator - basicAuthGroups []string - SkipProviderButton bool - skipAuthPreflight bool - skipJwtBearerTokens bool - forceJSONErrors bool - realClientIPParser ipapi.RealClientIPParser - trustedIPs *ip.NetSet + allowedRoutes []allowedRoute + apiRoutes []apiRoute + redirectURL *url.URL // the url to receive requests at + relativeRedirectURL bool + whitelistDomains []string + provider providers.Provider + sessionStore sessionsapi.SessionStore + ProxyPrefix string + basicAuthValidator basic.Validator + basicAuthGroups []string + SkipProviderButton bool + skipAuthPreflight bool + skipJwtBearerTokens bool + forceJSONErrors bool + allowQuerySemicolons bool + realClientIPParser ipapi.RealClientIPParser + trustedIPs *ip.NetSet sessionChain alice.Chain headersChain alice.Chain @@ -213,20 +214,21 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr SignInPath: fmt.Sprintf("%s/sign_in", opts.ProxyPrefix), - ProxyPrefix: opts.ProxyPrefix, - provider: provider, - sessionStore: sessionStore, - redirectURL: redirectURL, - relativeRedirectURL: opts.RelativeRedirectURL, - apiRoutes: apiRoutes, - allowedRoutes: allowedRoutes, - whitelistDomains: opts.WhitelistDomains, - skipAuthPreflight: opts.SkipAuthPreflight, - skipJwtBearerTokens: opts.SkipJwtBearerTokens, - realClientIPParser: opts.GetRealClientIPParser(), - SkipProviderButton: opts.SkipProviderButton, - forceJSONErrors: opts.ForceJSONErrors, - trustedIPs: trustedIPs, + ProxyPrefix: opts.ProxyPrefix, + provider: provider, + sessionStore: sessionStore, + redirectURL: redirectURL, + relativeRedirectURL: opts.RelativeRedirectURL, + apiRoutes: apiRoutes, + allowedRoutes: allowedRoutes, + whitelistDomains: opts.WhitelistDomains, + skipAuthPreflight: opts.SkipAuthPreflight, + skipJwtBearerTokens: opts.SkipJwtBearerTokens, + realClientIPParser: opts.GetRealClientIPParser(), + SkipProviderButton: opts.SkipProviderButton, + forceJSONErrors: opts.ForceJSONErrors, + allowQuerySemicolons: opts.AllowQuerySemicolons, + trustedIPs: trustedIPs, basicAuthValidator: basicAuthValidator, basicAuthGroups: opts.HtpasswdUserGroups, @@ -275,6 +277,11 @@ func (p *OAuthProxy) setupServer(opts *options.Options) error { TLS: opts.Server.TLS, } + // Option: AllowQuerySemicolons + if opts.AllowQuerySemicolons { + serverOpts.Handler = http.AllowQuerySemicolons(serverOpts.Handler) + } + appServer, err := proxyhttp.NewServer(serverOpts) if err != nil { return fmt.Errorf("could not build app server: %v", err) diff --git a/pkg/apis/options/options.go b/pkg/apis/options/options.go index ecf92808..49474c92 100644 --- a/pkg/apis/options/options.go +++ b/pkg/apis/options/options.go @@ -61,6 +61,7 @@ type Options struct { SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"` SkipAuthPreflight bool `flag:"skip-auth-preflight" cfg:"skip_auth_preflight"` ForceJSONErrors bool `flag:"force-json-errors" cfg:"force_json_errors"` + AllowQuerySemicolons bool `flag:"allow-query-semicolons" cfg:"allow_query_semicolons"` SignatureKey string `flag:"signature-key" cfg:"signature_key"` GCPHealthChecks bool `flag:"gcp-healthchecks" cfg:"gcp_healthchecks"` @@ -127,6 +128,7 @@ func NewFlagSet() *pflag.FlagSet { flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS providers") flagSet.Bool("skip-jwt-bearer-tokens", false, "will skip requests that have verified JWT bearer tokens (default false)") flagSet.Bool("force-json-errors", false, "will force JSON errors instead of HTTP error pages or redirects") + flagSet.Bool("allow-query-semicolons", false, "allow the use of semicolons in query args") flagSet.StringSlice("extra-jwt-issuers", []string{}, "if skip-jwt-bearer-tokens is set, a list of extra JWT issuer=audience pairs (where the issuer URL has a .well-known/openid-configuration or a .well-known/jwks.json)") flagSet.StringSlice("email-domain", []string{}, "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")