From 4d9031bdb2efafebc746429102ec8ccf617c7eec Mon Sep 17 00:00:00 2001 From: Romain Date: Mon, 18 May 2026 15:06:09 +0200 Subject: [PATCH] Add error on basic auth build if users is empty --- docs/content/migration/v2.md | 10 +++++++++- pkg/middlewares/auth/basic_auth.go | 4 ++++ pkg/middlewares/auth/basic_auth_test.go | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index c2a154e1e6..69baa2c9a9 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -826,7 +826,7 @@ environment variable to override the API version used by Traefik. ## v2.11.46 -### Kubernetes providers: `crossProviderNamespaces` +### Kubernetes Providers: `crossProviderNamespaces` In `v2.11.46`, a new `crossProviderNamespaces` option is available on the Kubernetes CRD, Ingress, and Gateway providers. @@ -848,3 +848,11 @@ The behavior is as follows: Please check out the [Kubernetes CRD](../providers/kubernetes-crd.md#crossprovidernamespaces), [Kubernetes Ingress](../providers/kubernetes-ingress.md#crossprovidernamespaces), and [Kubernetes Gateway](../providers/kubernetes-gateway.md#crossprovidernamespaces) provider documentation for more details. + +## v2.11.47 + +### BasicAuth Middleware + +From version `v2.11.47` onwards, the BasicAuth middleware requires a non-empty users configuration in order to be built successfully. +Previously, the middleware would be built successfully but always return a 401 status code for any request. +Now, an error occurs and any routers using it will be unmounted. For the same request, a 404 status code is served instead of a 401 status code. diff --git a/pkg/middlewares/auth/basic_auth.go b/pkg/middlewares/auth/basic_auth.go index 198c8ca84e..dcdb1f45c8 100644 --- a/pkg/middlewares/auth/basic_auth.go +++ b/pkg/middlewares/auth/basic_auth.go @@ -41,6 +41,10 @@ func NewBasic(ctx context.Context, next http.Handler, authConfig dynamic.BasicAu return nil, err } + if len(users) == 0 { + return nil, fmt.Errorf("no users found in %s", authConfig.UsersFile) + } + // To prevent timing attacks, we need to compute a hash even if the user is not found. // We assume it to be safe only when the users hashes are all from the same algorithm, // so we can pick the first one as a random hash to compute. diff --git a/pkg/middlewares/auth/basic_auth_test.go b/pkg/middlewares/auth/basic_auth_test.go index baabfba195..b7dd770133 100644 --- a/pkg/middlewares/auth/basic_auth_test.go +++ b/pkg/middlewares/auth/basic_auth_test.go @@ -14,6 +14,15 @@ import ( "github.com/traefik/traefik/v2/pkg/testhelpers" ) +func TestNewBasicEmpty(t *testing.T) { + auth := dynamic.BasicAuth{ + Users: []string{}, + } + + _, err := NewBasic(t.Context(), nil, auth, "authName") + require.Error(t, err) +} + func TestNewBasicNotFoundSecretIsSet(t *testing.T) { auth := dynamic.BasicAuth{ Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"},