fix: enforcement of defaults compatible with static upstreams

Signed-off-by: Jan Larwig <jan@larwig.com>
This commit is contained in:
Jan Larwig 2026-01-17 14:35:27 +01:00
parent c5019117ef
commit c43bbec23b
No known key found for this signature in database
GPG Key ID: C2172BFA220A037A
6 changed files with 61 additions and 30 deletions

View File

@ -9,7 +9,7 @@
## Changes since v7.14.0
- [#3309](https://github.com/oauth2-proxy/oauth2-proxy/pull/3309) fix: Return 302 redirect from AuthOnly endpoint when skip-provider-button is true (@StefanMarkmann)
- [#3302](https://github.com/oauth2-proxy/oauth2-proxy/pull/3302) fix: static upstreams failing validation due to `passHostHeader` and `proxyWebSockets` defaults being set incorrectly (@sourava01)
- [#3302](https://github.com/oauth2-proxy/oauth2-proxy/pull/3302) fix: static upstreams failing validation due to `passHostHeader` and `proxyWebSockets` defaults being set incorrectly (@sourava01 / @tuunit)
# V7.14.0

View File

@ -179,10 +179,10 @@ func (l *LegacyUpstreams) convert() (UpstreamConfig, error) {
upstream.URI = ""
upstream.InsecureSkipTLSVerify = ptr.To(false)
upstream.DisableKeepAlives = ptr.To(false)
upstream.PassHostHeader = nil
upstream.ProxyWebSockets = nil
upstream.FlushInterval = nil
upstream.Timeout = nil
upstream.PassHostHeader = ptr.To(false)
upstream.ProxyWebSockets = ptr.To(false)
upstream.FlushInterval = ptr.To(DefaultUpstreamFlushInterval)
upstream.Timeout = ptr.To(DefaultUpstreamTimeout)
case "unix":
upstream.Path = "/"
}

View File

@ -204,12 +204,12 @@ var _ = Describe("Legacy Options", func() {
URI: "",
Static: ptr.To(true),
StaticCode: &validStaticCode,
InsecureSkipTLSVerify: ptr.To(false),
PassHostHeader: nil,
ProxyWebSockets: nil,
FlushInterval: nil,
Timeout: nil,
DisableKeepAlives: ptr.To(false),
InsecureSkipTLSVerify: ptr.To(DefaultUpsteamInsecureSkipTLSVerify),
PassHostHeader: ptr.To(DefaultStaticPassHostHeader),
ProxyWebSockets: ptr.To(DefaultStaticProxyWebSockets),
FlushInterval: ptr.To(DefaultUpstreamFlushInterval),
Timeout: ptr.To(DefaultUpstreamTimeout),
DisableKeepAlives: ptr.To(DefaultUpstreamDisableKeepAlives),
}
invalidStatic := "static://abc"
@ -220,12 +220,12 @@ var _ = Describe("Legacy Options", func() {
URI: "",
Static: ptr.To(true),
StaticCode: &invalidStaticCode,
InsecureSkipTLSVerify: ptr.To(false),
PassHostHeader: nil,
ProxyWebSockets: nil,
FlushInterval: nil,
Timeout: nil,
DisableKeepAlives: ptr.To(false),
InsecureSkipTLSVerify: ptr.To(DefaultUpsteamInsecureSkipTLSVerify),
PassHostHeader: ptr.To(DefaultStaticPassHostHeader),
ProxyWebSockets: ptr.To(DefaultStaticProxyWebSockets),
FlushInterval: ptr.To(DefaultUpstreamFlushInterval),
Timeout: ptr.To(DefaultUpstreamTimeout),
DisableKeepAlives: ptr.To(DefaultUpstreamDisableKeepAlives),
}
invalidHTTP := ":foo"

View File

@ -29,9 +29,15 @@ const (
// DefaultUpstreamPassHostHeader determines if upstreams will pass the host header by default.
DefaultUpstreamPassHostHeader bool = true
// Static upstreams cannot pass the host header.
DefaultStaticPassHostHeader bool = false
// DefaultUpstreamProxyWebSockets determines if upstreams will proxy websockets by default.
DefaultUpstreamProxyWebSockets bool = true
// Static upstreams cannot proxy websockets.
DefaultStaticProxyWebSockets bool = false
// DefaultUpstreamDisableKeepAlives determines if upstreams will disable keep-alives by default.
DefaultUpstreamDisableKeepAlives bool = false
)
@ -143,6 +149,12 @@ func (u *Upstream) EnsureDefaults() {
if u.Static == nil {
u.Static = ptr.To(DefaultUpstreamStatic)
}
if u.PassHostHeader == nil {
u.PassHostHeader = ptr.To(DefaultUpstreamPassHostHeader)
}
if u.ProxyWebSockets == nil {
u.ProxyWebSockets = ptr.To(DefaultUpstreamProxyWebSockets)
}
if u.FlushInterval == nil {
u.FlushInterval = ptr.To(DefaultUpstreamFlushInterval)
}
@ -153,14 +165,15 @@ func (u *Upstream) EnsureDefaults() {
u.DisableKeepAlives = ptr.To(DefaultUpstreamDisableKeepAlives)
}
// PassHostHeader and ProxyWebSockets must remain nil for static upstreams
// as they don't apply and validation will flag them if set
if !ptr.Deref(u.Static, DefaultUpstreamStatic) {
if u.PassHostHeader == nil {
u.PassHostHeader = ptr.To(DefaultUpstreamPassHostHeader)
}
if u.ProxyWebSockets == nil {
u.ProxyWebSockets = ptr.To(DefaultUpstreamProxyWebSockets)
}
// Force defaults compatible with static upstreams.
// This overrides any user provided values to ensure static upstreams behave correctly.
if ptr.Deref(u.Static, DefaultUpstreamStatic) {
u.URI = ""
u.InsecureSkipTLSVerify = ptr.To(DefaultUpsteamInsecureSkipTLSVerify)
u.DisableKeepAlives = ptr.To(DefaultUpstreamDisableKeepAlives)
u.PassHostHeader = ptr.To(DefaultStaticPassHostHeader)
u.ProxyWebSockets = ptr.To(DefaultStaticProxyWebSockets)
u.FlushInterval = ptr.To(DefaultUpstreamFlushInterval)
u.Timeout = ptr.To(DefaultUpstreamTimeout)
}
}

View File

@ -70,13 +70,13 @@ func validateStaticUpstream(upstream options.Upstream) []string {
if ptr.Deref(upstream.InsecureSkipTLSVerify, options.DefaultUpsteamInsecureSkipTLSVerify) {
msgs = append(msgs, fmt.Sprintf("upstream %q has insecureSkipTLSVerify, but is a static upstream, this will have no effect.", upstream.ID))
}
if upstream.FlushInterval != nil && *upstream.FlushInterval != options.DefaultUpstreamFlushInterval {
if ptr.Deref(upstream.FlushInterval, options.DefaultUpstreamFlushInterval) != options.DefaultUpstreamFlushInterval {
msgs = append(msgs, fmt.Sprintf("upstream %q has flushInterval, but is a static upstream, this will have no effect.", upstream.ID))
}
if upstream.PassHostHeader != nil {
if ptr.Deref(upstream.PassHostHeader, options.DefaultStaticPassHostHeader) != options.DefaultStaticPassHostHeader {
msgs = append(msgs, fmt.Sprintf("upstream %q has passHostHeader, but is a static upstream, this will have no effect.", upstream.ID))
}
if upstream.ProxyWebSockets != nil {
if ptr.Deref(upstream.ProxyWebSockets, options.DefaultStaticProxyWebSockets) != options.DefaultStaticProxyWebSockets {
msgs = append(msgs, fmt.Sprintf("upstream %q has proxyWebSockets, but is a static upstream, this will have no effect.", upstream.ID))
}

View File

@ -138,7 +138,7 @@ var _ = Describe("Upstreams", func() {
},
errStrings: []string{invalidURISchemeMsg},
}),
Entry("with a static upstream and invalid optons", &validateUpstreamTableInput{
Entry("with a static upstream and invalid options", &validateUpstreamTableInput{
upstreams: options.UpstreamConfig{
Upstreams: []options.Upstream{
{
@ -161,6 +161,24 @@ var _ = Describe("Upstreams", func() {
staticWithProxyWebSocketsMsg,
},
}),
Entry("with a static upstream and sane default options", &validateUpstreamTableInput{
upstreams: options.UpstreamConfig{
Upstreams: []options.Upstream{
{
ID: "foo",
Path: "/foo",
URI: "ftp://foo",
Static: ptr.To(true),
PassHostHeader: ptr.To(false),
ProxyWebSockets: ptr.To(false),
InsecureSkipTLSVerify: ptr.To(false),
},
},
},
errStrings: []string{
staticWithURIMsg,
},
}),
Entry("with duplicate IDs", &validateUpstreamTableInput{
upstreams: options.UpstreamConfig{
Upstreams: []options.Upstream{