diff --git a/docs/content/middlewares/http/forwardauth.md b/docs/content/middlewares/http/forwardauth.md index 1b2ae3eb22..b98184cf89 100644 --- a/docs/content/middlewares/http/forwardauth.md +++ b/docs/content/middlewares/http/forwardauth.md @@ -637,4 +637,65 @@ http: [http.middlewares.test-auth.forwardAuth.tls] insecureSkipVerify: true ``` + +### `maxResponseBodySize` + +_Optional, Default=-1_ + +The `maxResponseBodySize` option defines the maximum allowed response body size in bytes from the authentication server. +If the response body exceeds the configured limit, the request is rejected with a 401 (Unauthorized) status. +If left unset, the request body size is unrestricted which can have performance or security implications. + +```yaml tab="Docker" +labels: + - "traefik.http.middlewares.test-auth.forwardauth.maxResponseBodySize=10000" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: test-auth +spec: + forwardAuth: + address: https://example.com/auth + maxResponseBodySize: 10000 +``` + +```yaml tab="Consul Catalog" +- "traefik.http.middlewares.test-auth.forwardauth.maxResponseBodySize=10000" +``` + +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.test-auth.forwardauth.maxResponseBodySize": "10000" +} +``` + +```yaml tab="Rancher" +labels: + - "traefik.http.middlewares.test-auth.forwardauth.maxResponseBodySize=10000" +``` + +```yaml tab="File (YAML)" +http: + middlewares: + test-auth: + forwardAuth: + address: "https://example.com/auth" + maxResponseBodySize: 10000 +``` + +```toml tab="File (TOML)" +[http.middlewares] + [http.middlewares.test-auth.forwardAuth] + address = "https://example.com/auth" + maxResponseBodySize = 10000 +``` + +!!! warning + + It is strongly recommended to set this option to a suitable value. + Not setting it (or setting it to `-1`) allows unlimited response body sizes which can lead to DoS attacks and memory exhaustion. + {% include-markdown "includes/traefik-for-business-applications.md" %} diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index 586952361c..8321f1d04c 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -764,3 +764,14 @@ in [RFC3986 section-3](https://datatracker.ietf.org/doc/html/rfc3986#section-3). Please check out the entrypoint [encodedCharacters option](../routing/entrypoints.md#encoded-characters) documentation for more details. + +## v2.11.38 + +### `maxResponseBodySize` configuration on ForwardAuth middleware + +In `v2.11.38`, a new `maxResponseBodySize` option has been added to the ForwardAuth middleware configuration. +The default value for this option is -1, which means there is no limit to the response body size. +However, it is strongly recommended to set this option to a suitable value to avoid performance and security issues, +such as DoS attacks and memory exhaustion. + +Please check out the [ForwardAuth](../middlewares/http/forwardauth.md#maxresponsebodysize) middleware documentation for more details. diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml index 02ac9eb1fd..5609baa15a 100644 --- a/docs/content/reference/dynamic-configuration/docker-labels.yml +++ b/docs/content/reference/dynamic-configuration/docker-labels.yml @@ -32,6 +32,7 @@ - "traefik.http.middlewares.middleware10.forwardauth.authrequestheaders=foobar, foobar" - "traefik.http.middlewares.middleware10.forwardauth.authresponseheaders=foobar, foobar" - "traefik.http.middlewares.middleware10.forwardauth.authresponseheadersregex=foobar" +- "traefik.http.middlewares.middleware10.forwardauth.maxresponsebodysize=42" - "traefik.http.middlewares.middleware10.forwardauth.tls.ca=foobar" - "traefik.http.middlewares.middleware10.forwardauth.tls.caoptional=true" - "traefik.http.middlewares.middleware10.forwardauth.tls.cert=foobar" diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index fc04a29c66..9469eb118e 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -155,6 +155,7 @@ authResponseHeaders = ["foobar", "foobar"] authResponseHeadersRegex = "foobar" authRequestHeaders = ["foobar", "foobar"] + maxResponseBodySize = 42 [http.middlewares.Middleware10.forwardAuth.tls] ca = "foobar" caOptional = true diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index ec861d0a2d..f4820dc2fd 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -176,6 +176,7 @@ http: authRequestHeaders: - foobar - foobar + maxResponseBodySize: 42 Middleware11: headers: customRequestHeaders: diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml index a968bea60f..5173576a3a 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -1001,6 +1001,11 @@ spec: AuthResponseHeadersRegex defines the regex to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the regex. More info: https://doc.traefik.io/traefik/v2.11/middlewares/http/forwardauth/#authresponseheadersregex type: string + maxResponseBodySize: + description: MaxResponseBodySize defines the maximum body size + in bytes allowed in the response from the authentication server. + format: int64 + type: integer tls: description: TLS defines the configuration used to secure the connection to the authentication server. diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index 0b2f7c5f08..2b23e402ba 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -43,6 +43,7 @@ THIS FILE MUST NOT BE EDITED BY HAND | `traefik/http/middlewares/Middleware10/forwardAuth/authResponseHeaders/0` | `foobar` | | `traefik/http/middlewares/Middleware10/forwardAuth/authResponseHeaders/1` | `foobar` | | `traefik/http/middlewares/Middleware10/forwardAuth/authResponseHeadersRegex` | `foobar` | +| `traefik/http/middlewares/Middleware10/forwardAuth/maxResponseBodySize` | `42` | | `traefik/http/middlewares/Middleware10/forwardAuth/tls/ca` | `foobar` | | `traefik/http/middlewares/Middleware10/forwardAuth/tls/caOptional` | `true` | | `traefik/http/middlewares/Middleware10/forwardAuth/tls/cert` | `foobar` | diff --git a/docs/content/reference/dynamic-configuration/marathon-labels.json b/docs/content/reference/dynamic-configuration/marathon-labels.json index 41fa198bd9..2a3f2a366e 100644 --- a/docs/content/reference/dynamic-configuration/marathon-labels.json +++ b/docs/content/reference/dynamic-configuration/marathon-labels.json @@ -32,6 +32,7 @@ "traefik.http.middlewares.middleware10.forwardauth.authrequestheaders": "foobar, foobar", "traefik.http.middlewares.middleware10.forwardauth.authresponseheaders": "foobar, foobar", "traefik.http.middlewares.middleware10.forwardauth.authresponseheadersregex": "foobar", +"traefik.http.middlewares.middleware10.forwardauth.maxresponsebodysize": "42", "traefik.http.middlewares.middleware10.forwardauth.tls.ca": "foobar", "traefik.http.middlewares.middleware10.forwardauth.tls.caoptional": "true", "traefik.http.middlewares.middleware10.forwardauth.tls.cert": "foobar", diff --git a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml index defa3a5bfb..fd0f7beaa0 100644 --- a/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml @@ -386,6 +386,11 @@ spec: AuthResponseHeadersRegex defines the regex to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the regex. More info: https://doc.traefik.io/traefik/v2.11/middlewares/http/forwardauth/#authresponseheadersregex type: string + maxResponseBodySize: + description: MaxResponseBodySize defines the maximum body size + in bytes allowed in the response from the authentication server. + format: int64 + type: integer tls: description: TLS defines the configuration used to secure the connection to the authentication server. diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index a968bea60f..5173576a3a 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -1001,6 +1001,11 @@ spec: AuthResponseHeadersRegex defines the regex to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the regex. More info: https://doc.traefik.io/traefik/v2.11/middlewares/http/forwardauth/#authresponseheadersregex type: string + maxResponseBodySize: + description: MaxResponseBodySize defines the maximum body size + in bytes allowed in the response from the authentication server. + format: int64 + type: integer tls: description: TLS defines the configuration used to secure the connection to the authentication server. diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index 8af6944a02..a1d49f75c2 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -216,6 +216,8 @@ type ForwardAuth struct { // AuthRequestHeaders defines the list of the headers to copy from the request to the authentication server. // If not set or empty then all request headers are passed. AuthRequestHeaders []string `json:"authRequestHeaders,omitempty" toml:"authRequestHeaders,omitempty" yaml:"authRequestHeaders,omitempty" export:"true"` + // MaxResponseBodySize defines the maximum body size in bytes allowed in the response from the authentication server. + MaxResponseBodySize *int64 `json:"maxResponseBodySize,omitempty" toml:"maxResponseBodySize,omitempty" yaml:"maxResponseBodySize,omitempty" export:"true"` } // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/zz_generated.deepcopy.go b/pkg/config/dynamic/zz_generated.deepcopy.go index b8f68c946a..c9cf5d446f 100644 --- a/pkg/config/dynamic/zz_generated.deepcopy.go +++ b/pkg/config/dynamic/zz_generated.deepcopy.go @@ -324,6 +324,11 @@ func (in *ForwardAuth) DeepCopyInto(out *ForwardAuth) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.MaxResponseBodySize != nil { + in, out := &in.MaxResponseBodySize, &out.MaxResponseBodySize + *out = new(int64) + **out = **in + } return } diff --git a/pkg/config/label/label_test.go b/pkg/config/label/label_test.go index b4c209e4cf..e620ffb7ab 100644 --- a/pkg/config/label/label_test.go +++ b/pkg/config/label/label_test.go @@ -50,6 +50,7 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.http.middlewares.Middleware7.forwardauth.tls.insecureskipverify": "true", "traefik.http.middlewares.Middleware7.forwardauth.tls.key": "foobar", "traefik.http.middlewares.Middleware7.forwardauth.trustforwardheader": "true", + "traefik.http.middlewares.Middleware7.forwardauth.maxresponsebodysize": "42", "traefik.http.middlewares.Middleware8.headers.accesscontrolallowcredentials": "true", "traefik.http.middlewares.Middleware8.headers.allowedhosts": "foobar, fiibar", "traefik.http.middlewares.Middleware8.headers.accesscontrolallowheaders": "X-foobar, X-fiibar", @@ -547,6 +548,7 @@ func TestDecodeConfiguration(t *testing.T) { "foobar", "fiibar", }, + MaxResponseBodySize: pointer[int64](42), }, }, "Middleware8": { @@ -1060,6 +1062,7 @@ func TestEncodeConfiguration(t *testing.T) { "foobar", "fiibar", }, + MaxResponseBodySize: pointer[int64](42), }, }, "Middleware8": { @@ -1259,6 +1262,7 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.InsecureSkipVerify": "true", "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Key": "foobar", "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TrustForwardHeader": "true", + "traefik.HTTP.Middlewares.Middleware7.ForwardAuth.MaxResponseBodySize": "42", "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowCredentials": "true", "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowHeaders": "X-foobar, X-fiibar", "traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowMethods": "GET, PUT", diff --git a/pkg/middlewares/auth/forward.go b/pkg/middlewares/auth/forward.go index 6004a01fa9..cf0801af45 100644 --- a/pkg/middlewares/auth/forward.go +++ b/pkg/middlewares/auth/forward.go @@ -47,11 +47,13 @@ type forwardAuth struct { client http.Client trustForwardHeader bool authRequestHeaders []string + maxResponseBodySize int64 } // NewForward creates a forward auth middleware. func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAuth, name string) (http.Handler, error) { - log.FromContext(middlewares.GetLoggerCtx(ctx, name, forwardedTypeName)).Debug("Creating middleware") + logger := log.FromContext(middlewares.GetLoggerCtx(ctx, name, forwardedTypeName)) + logger.Debug("Creating middleware") fa := &forwardAuth{ address: config.Address, @@ -62,6 +64,13 @@ func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAu authRequestHeaders: config.AuthRequestHeaders, } + if config.MaxResponseBodySize != nil { + fa.maxResponseBodySize = *config.MaxResponseBodySize + } else { + fa.maxResponseBodySize = -1 + logger.Warn("ForwardAuth 'maxResponseBodySize' is not configured, allowing unlimited response body size which can lead to DoS attacks and memory exhaustion. Please set an appropriate limit.") + } + // Ensure our request client does not follow redirects fa.client = http.Client{ CheckRedirect: func(r *http.Request, via []*http.Request) error { @@ -125,9 +134,16 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } defer forwardResponse.Body.Close() - body, readError := io.ReadAll(forwardResponse.Body) + body, readError := fa.readResponseBodyBytes(forwardResponse) if readError != nil { - logger.Debugf("Error reading body %s. Cause: %s", fa.address, readError) + if errors.Is(readError, errResponseBodyTooLarge) { + logger.Debugf("Response body is too large, maxResponseBodySize: %d", fa.maxResponseBodySize) + + tracing.SetErrorWithEvent(req, "Response body is too large, maxResponseBodySize: %d", fa.maxResponseBodySize) + rw.WriteHeader(http.StatusUnauthorized) + return + } + logger.Debugf("Error reading body %s", fa.address) tracing.SetErrorWithEvent(req, "Error reading body %s. Cause: %s", fa.address, readError) rw.WriteHeader(http.StatusInternalServerError) @@ -193,6 +209,27 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { fa.next.ServeHTTP(rw, req) } +var errResponseBodyTooLarge = errors.New("response body too large") + +func (fa *forwardAuth) readResponseBodyBytes(res *http.Response) ([]byte, error) { + if fa.maxResponseBodySize < 0 { + return io.ReadAll(res.Body) + } + + body := make([]byte, fa.maxResponseBodySize+1) + n, err := io.ReadFull(res.Body, body) + if errors.Is(err, io.EOF) { + return nil, nil + } + if err != nil && !errors.Is(err, io.ErrUnexpectedEOF) { + return nil, fmt.Errorf("reading response body bytes: %w", err) + } + if errors.Is(err, io.ErrUnexpectedEOF) { + return body[:n], nil + } + return nil, errResponseBodyTooLarge +} + func writeHeader(req, forwardReq *http.Request, trustForwardHeader bool, allowedHeaders []string) { utils.CopyHeaders(forwardReq.Header, req.Header) diff --git a/pkg/middlewares/auth/forward_test.go b/pkg/middlewares/auth/forward_test.go index 3dbd4eece2..952fc8b751 100644 --- a/pkg/middlewares/auth/forward_test.go +++ b/pkg/middlewares/auth/forward_test.go @@ -482,6 +482,89 @@ func TestForwardAuthUsesTracing(t *testing.T) { assert.Equal(t, http.StatusOK, res.StatusCode) } +func Test_ForwardAuthMaxResponseBodySize(t *testing.T) { + testCases := []struct { + name string + maxResponseBodySize int64 + status int + body string + expectedStatus int + expectedBody string + }{ + { + name: "auth failure, unlimited response body", + maxResponseBodySize: -1, + status: http.StatusForbidden, + body: "Forbidden", + expectedStatus: http.StatusForbidden, + expectedBody: "Forbidden", + }, + { + name: "auth failure, response body exceeds the limit", + maxResponseBodySize: 1, + status: http.StatusForbidden, + body: "Forbidden", + expectedStatus: http.StatusUnauthorized, + expectedBody: "", + }, + { + name: "auth success within limit", + maxResponseBodySize: 100, + status: http.StatusOK, + body: "ok", + expectedStatus: http.StatusOK, + expectedBody: "traefik\n", + }, + { + name: "auth success body exceeds limit", + maxResponseBodySize: 1, + status: http.StatusOK, + body: "large auth response", + expectedStatus: http.StatusUnauthorized, + expectedBody: "", + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(test.status) + fmt.Fprint(w, test.body) + })) + t.Cleanup(server.Close) + + next := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "traefik") + })) + + maxResponseBodySize := test.maxResponseBodySize + auth := dynamic.ForwardAuth{ + Address: server.URL, + MaxResponseBodySize: &maxResponseBodySize, + } + + middleware, err := NewForward(t.Context(), next, auth, "maxResponseBodySizeTest") + require.NoError(t, err) + + ts := httptest.NewServer(middleware) + t.Cleanup(ts.Close) + + req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil) + res, err := http.DefaultClient.Do(req) + require.NoError(t, err) + + assert.Equal(t, test.expectedStatus, res.StatusCode) + + body, err := io.ReadAll(res.Body) + require.NoError(t, err) + err = res.Body.Close() + require.NoError(t, err) + + assert.Equal(t, test.expectedBody, string(body)) + }) + } +} + type mockBackend struct { opentracing.Tracer } diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index 79954288b2..eca0a876d7 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -652,6 +652,10 @@ func createForwardAuthMiddleware(k8sClient Client, namespace string, auth *traef AuthRequestHeaders: auth.AuthRequestHeaders, } + if auth.MaxResponseBodySize != nil { + forwardAuth.MaxResponseBodySize = auth.MaxResponseBodySize + } + if auth.TLS == nil { return forwardAuth, nil } diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go index 21c1e3cfba..7e448faaee 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go @@ -155,6 +155,8 @@ type ForwardAuth struct { AuthRequestHeaders []string `json:"authRequestHeaders,omitempty"` // TLS defines the configuration used to secure the connection to the authentication server. TLS *ClientTLS `json:"tls,omitempty"` + // MaxResponseBodySize defines the maximum body size in bytes allowed in the response from the authentication server. + MaxResponseBodySize *int64 `json:"maxResponseBodySize,omitempty"` } // ClientTLS holds the client TLS configuration. diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go index ebd5e9ce24..07f33f0cac 100644 --- a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go @@ -215,6 +215,11 @@ func (in *ForwardAuth) DeepCopyInto(out *ForwardAuth) { *out = new(ClientTLS) **out = **in } + if in.MaxResponseBodySize != nil { + in, out := &in.MaxResponseBodySize, &out.MaxResponseBodySize + *out = new(int64) + **out = **in + } return } diff --git a/pkg/provider/kv/kv_test.go b/pkg/provider/kv/kv_test.go index 3d3fdad2fd..92038905e7 100644 --- a/pkg/provider/kv/kv_test.go +++ b/pkg/provider/kv/kv_test.go @@ -83,6 +83,7 @@ func Test_buildConfiguration(t *testing.T) { "traefik/http/middlewares/Middleware08/forwardAuth/tls/cert": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/address": "foobar", "traefik/http/middlewares/Middleware08/forwardAuth/trustForwardHeader": "true", + "traefik/http/middlewares/Middleware08/forwardAuth/maxResponseBodySize": "42", "traefik/http/middlewares/Middleware15/redirectScheme/scheme": "foobar", "traefik/http/middlewares/Middleware15/redirectScheme/port": "foobar", "traefik/http/middlewares/Middleware15/redirectScheme/permanent": "true", @@ -427,6 +428,7 @@ func Test_buildConfiguration(t *testing.T) { "foobar", "foobar", }, + MaxResponseBodySize: pointer[int64](42), }, }, "Middleware06": { diff --git a/pkg/redactor/redactor_config_test.go b/pkg/redactor/redactor_config_test.go index f96eb04fa0..2364494b01 100644 --- a/pkg/redactor/redactor_config_test.go +++ b/pkg/redactor/redactor_config_test.go @@ -287,6 +287,7 @@ func init() { AuthResponseHeaders: []string{"foo"}, AuthResponseHeadersRegex: "foo", AuthRequestHeaders: []string{"foo"}, + MaxResponseBodySize: pointer[int64](42), }, InFlightReq: &dynamic.InFlightReq{ Amount: 42, diff --git a/pkg/redactor/testdata/anonymized-dynamic-config.json b/pkg/redactor/testdata/anonymized-dynamic-config.json index 8339f58c3c..7501d83885 100644 --- a/pkg/redactor/testdata/anonymized-dynamic-config.json +++ b/pkg/redactor/testdata/anonymized-dynamic-config.json @@ -247,7 +247,8 @@ "authResponseHeadersRegex": "foo", "authRequestHeaders": [ "foo" - ] + ], + "maxResponseBodySize": 42 }, "inFlightReq": { "amount": 42, diff --git a/pkg/redactor/testdata/secured-dynamic-config.json b/pkg/redactor/testdata/secured-dynamic-config.json index 352421884d..34f0720080 100644 --- a/pkg/redactor/testdata/secured-dynamic-config.json +++ b/pkg/redactor/testdata/secured-dynamic-config.json @@ -250,7 +250,8 @@ "authResponseHeadersRegex": "foo", "authRequestHeaders": [ "foo" - ] + ], + "maxResponseBodySize": 42 }, "inFlightReq": { "amount": 42,