fix(deps): update module github.com/traefik/traefik/v2 to v2.11.44 [security]#555
Open
renovate[bot] wants to merge 1 commit into
Open
fix(deps): update module github.com/traefik/traefik/v2 to v2.11.44 [security]#555renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
ec0d285 to
af87c31
Compare
af87c31 to
c1070c7
Compare
c1070c7 to
c23edb4
Compare
c23edb4 to
55b9674
Compare
Contributor
Author
ℹ️ Artifact update noticeFile name: go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
v2.11.41→v2.11.44Traefik Vulnerable to BasicAuth/DigestAuth Identity Spoofing via Non-Canonical headerField
CVE-2026-33433 / GHSA-qr99-7898-vr7c
More information
Details
Summary
There is a potential vulnerability in Traefik's Basic and Digest authentication middlewares when
headerFieldis configured with a non-canonical HTTP header name.An authenticated attacker with valid credentials can inject the canonical version of the configured header to impersonate any identity to the backend. Because Traefik writes the authenticated username using a non-canonical map key, it creates a separate header entry rather than overwriting the attacker's canonical one — causing most backend frameworks to read the attacker-controlled value instead.
Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
Summary
When
headerFieldis configured with a non-canonical HTTP header name (e.g.,x-auth-userinstead ofX-Auth-User), an authenticated attacker can inject a canonical version of that header to impersonate any identity to the backend. The backend receives two header entries — the attacker-injected canonical one is read first, overriding Traefik's non-canonical write.Tested on Traefik v3.6.10.
Details
At
pkg/middlewares/auth/basic_auth.go:92, the authenticated username is written using direct map assignment:Go's
http.Headermap is keyed by canonical names (e.g.,X-Auth-User). Direct assignment with a non-canonical key (x-auth-user) creates a separate map entry from any canonical-key entry already present. The attacker'sX-Auth-User: superadminoccupies the canonical slot and is never overwritten by Traefik's non-canonical write.The same bug exists in
pkg/middlewares/auth/digest_auth.go:100. Notably,forward.go:254correctly useshttp.CanonicalHeaderKey(), showing the fix pattern already exists in the codebase.PoC
Traefik config (YAML, Docker labels, or REST API):
Normal request (baseline):
Attack request:
Control test — when
headerFielduses canonical casing (X-Auth-User), the attack fails. Traefik's write correctly overwrites the attacker's header.This is realistic because YAML conventions favor lowercase keys, Traefik docs don't warn about canonicalization, and the pattern of backends trusting the
headerFieldheader is recommended in Traefik's own documentation.Fix suggestion:
Also strip any incoming
headerFieldheader before the auth check withreq.Header.Del(b.headerField).Impact
An authenticated attacker with valid credentials (even low-privilege) can impersonate any other user identity to backend services. If backends use the
headerFieldheader for authorization decisions (which is the intended use case per Traefik docs), this enables privilege escalation — e.g., a regular user impersonating an admin.The attack requires the operator to configure
headerFieldwith a non-canonical header name, which is the natural thing to do in YAML and is not warned against in documentation.Severity
CVSS:4.0/AV:N/AC:H/AT:P/PR:H/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Traefik: Deny Rule Bypass via Unauthenticated Malicious gRPC Requests in gRPC-Go Dependency (CVE-2026-33186)
GHSA-46wh-3698-f2cx
More information
Details
Summary
There is a potential vulnerability in Traefik due to its dependency on an affected version of gRPC-Go (CVE-2026-33186).
A remote, unauthenticated attacker can send gRPC requests with a malformed HTTP/2
:pathpseudo-header omitting the mandatory leading slash (e.g.,Service/Methodinstead of/Service/Method). While the server routes such requests correctly, path-based authorization interceptors evaluate the raw non-canonical path and fail to match "deny" rules, allowing the request to bypass the policy entirely if a fallback "allow" rule is present.Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
Summary
This CVE hits traefik until Version 3.6.11 and 2.11.41.
gRPC-Go has an authorization bypass via missing leading slash in :path
Details
As described in GHSA-p77j-4mvh-x3m3
PoC
Update library version in
https://github.com/traefik/traefik/blob/67c64ed9b25fbb90f1086977a62827133a7aa01b/go.mod#L108
Impact
Is described in GHSA-p77j-4mvh-x3m3
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Traefik's ForwardAuth trustForwardHeader=false allows spoofed X-Forwarded-Prefix to bypass authentication
CVE-2026-35051 / GHSA-6384-m2mw-rf54
More information
Details
Summary
There is a high-severity authentication bypass vulnerability in Traefik's
ForwardAuthmiddleware whentrustForwardHeader=falseis configured and Traefik is deployed behind a trusted upstream proxy.While
X-Forwarded-*headers (such asX-Forwarded-For,X-Forwarded-Host, andX-Forwarded-Proto) from trusted context are correctly rebuilt, it does not strip or rebuildX-Forwarded-Prefix, leaving any attacker-supplied value intact in the subrequest forwarded to the authentication service.When the authentication service makes authorization decisions based on
X-Forwarded-Prefix, an external attacker can spoof a trusted prefix value and gain unauthorized access to protected backend routes.Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
Summary
ForwardAuthwithtrustForwardHeader=falsestill forwards an attacker-controlledX-Forwarded-Prefixheader to the authentication service when Traefik is deployed behind a trusted upstream proxy. If the auth service relies onX-Forwarded-Prefixfor authorization or routing decisions, an external attacker can bypass access controls and reach protected backend routes.This was validated this against Traefik
v3.6.12using the official Docker image and a minimal local Docker setup. A direct request to Traefik is correctly rejected, but the same request succeeds when sent through a trusted reverse proxy, which shows the issue is in theForwardAuthsubrequest handling rather than general ingress header stripping.Details
The vulnerable behavior comes from the way Traefik builds the subrequest sent to the forward-auth server.
In
pkg/middlewares/auth/forward.go,writeHeaderfirst copies all incoming request headers into the auth subrequest:It then selectively rebuilds only a subset of forwarded headers when
trustForwardHeader=false, for example:X-Forwarded-ForX-Forwarded-MethodX-Forwarded-ProtoX-Forwarded-PortX-Forwarded-HostX-Forwarded-UriHowever, it does not remove or rebuild
X-Forwarded-Prefix, so an attacker-supplied value remains in the auth request even when forwarded headers are supposed to be untrusted.This becomes security-relevant when
StripPrefixis used beforeForwardAuth. Inpkg/middlewares/stripprefix/strip_prefix.go, Traefik appends the stripped prefix usingHeader.Add:If the attacker already sent
X-Forwarded-Prefix: /admin, andStripPrefixlater adds/forbidden, the auth service receives both values in this order:/admin(attacker-controlled)/forbidden(Traefik-generated)An auth service that uses the first
X-Forwarded-Prefixvalue can therefore be tricked into authorizing a protected route.Why this appears unintended:
trustForwardHeadermeans "Trust all X-Forwarded-* headers" and defaults tofalse.X-Forwarded-Prefixis handled like otherX-Forwarded-*headers and removed from untrusted sources.403.X-Forwarded-Prefix.Relevant source/documentation locations:
pkg/middlewares/auth/forward.golines 393-459pkg/middlewares/stripprefix/strip_prefix.golines 65-68pkg/middlewares/forwardedheaders/forwarded_header.golines 15-43docs/content/reference/routing-configuration/http/middlewares/forwardauth.mdlines 59-62 and 130-140docs/content/migrate/v3.mdlines 192-196This was only tested and validated with
X-Forwarded-Prefix. By source review, other forwarded headers that are copied but not rebuilt inwriteHeadermay deserve separate review, but I am not claiming impact for them here.PoC
The following uses the official
traefik:v3.6.12Docker image and a mountedtraefik.toml, matching the documented deployment style.traefik.toml:dynamic.toml:auth.py:frontend.conf:Direct to Traefik, spoofed header:
Expected result:
Through trusted proxy, no spoofing:
curl -sS -i \ -H 'Host: app.local' \ http://127.0.0.1:18080/forbidden/testExpected result:
Through trusted proxy, spoofed header:
Observed result:
The backend response confirms that the request reached the protected upstream after the auth service accepted the attacker-controlled prefix.
Observed log sequence:
{"path": "/check", "first_prefix": "/forbidden", "all_prefixes": ["/forbidden"], ...} {"path": "/check", "first_prefix": "/forbidden", "all_prefixes": ["/forbidden"], ...} {"path": "/check", "first_prefix": "/admin", "all_prefixes": ["/admin", "/forbidden"], ...}Impact
This is an authentication bypass / trust-boundary bypass.
Affected deployments are those that:
ForwardAuthtrustForwardHeader=falseto avoid trusting client-supplied forwarded headersX-Forwarded-Prefixto the auth service, which happens by default whenauthRequestHeadersis emptyX-Forwarded-Prefix, especially whenStripPrefixruns beforeForwardAuthIn those environments, an unauthenticated external attacker can influence the auth service's view of the protected path and gain access to backend routes that should be denied.
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Traefik: Pre-authentication decision bypass due to forwarded alias spoofing
CVE-2026-39858 / GHSA-5m6w-wvh7-57vm
More information
Details
Summary
There is a high severity authentication bypass vulnerability in Traefik's
ForwardAuthand snippet-based authentication middleware. Traefik's forwarded-header sanitization logic targets only canonical header names (e.g.,X-Forwarded-Proto) and does not strip or normalize alias variants that use underscores instead of dashes (e.g.,X_Forwarded_Proto). These unsanitized alias headers are forwarded intact to the authentication backend. When the backend normalizes underscore and dash header forms equivalently, an attacker can inject spoofed trust context — such as a trusted scheme or host — through the alias headers and bypass authentication on protected routes without valid credentials.Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
Summary
An authentication bypass arises from chaining two bugs: incomplete forwarded-header sanitization at ingress and overly permissive header forwarding in pre-auth subrequests. While canonical
X-Forwarded-*headers are handled, alias variants (e.g., underscore forms) are neither normalized nor stripped consistently. When downstream auth services normalize these headers, attackers can inject trusted context and bypass authentication on protected routes without credentials.Details
This issue results from the interaction between forwarded-header handling and auth subrequest construction, creating a trust boundary mismatch.
At ingress, Traefik defines a fixed set of canonical forwarded headers (
X-Forwarded-Proto,X-Forwarded-For, etc.):Reference :
pkg/middlewares/forwardedheaders/forwarded_header.go#L29-L36This logic focuses exclusively on canonical header names and does not account for alias forms such as
X_Forwarded_Proto. As a result, while standard headers may be sanitized or rewritten, semantically equivalent variants can pass through unchanged.During ForwardAuth processing, request headers are copied wholesale into the auth subrequest:
Reference :
pkg/middlewares/auth/forward.go#L401-L408This implementation forwards nearly all client-supplied headers to the auth backend, with filtering limited to hop-by-hop headers. There is no normalization or deduplication between canonical and alias header forms, meaning attacker-controlled headers can reach the auth service intact.
A similar pattern exists in snippet-based auth:
Reference :
pkg/middlewares/ingressnginx/snippet/snippet.go#L574-L581Again, headers are forwarded without enforcing a consistent trust model or canonicalization.
The vulnerability emerges when the auth backend normalizes header names (e.g., treating
X_Forwarded_ProtoandX-Forwarded-Protoequivalently). In that case:This allows a single crafted request to simultaneously bypass ingress trust enforcement and satisfy authentication checks, resulting in unauthorized access to protected backends.
PoC
Impact
This vulnerability allows unauthenticated attackers to bypass authentication at the proxy-to-auth boundary by injecting spoofed trust context through header aliases. In deployments where authorization decisions depend on forwarded headers, attackers can access protected endpoints and interact with backend services as if they were fully authenticated. This effectively undermines ForwardAuth and similar mechanisms, potentially exposing sensitive internal functionality and data.
Suggested Remediation
X-Forwarded-*).Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Traefik has an StripPrefixRegex Middleware Authorization Bypass via Path/RawPath Desync
CVE-2026-40912 / GHSA-6jwx-7vp4-9847
More information
Details
Summary
There is a high severity authentication bypass vulnerability in Traefik's
StripPrefixRegexmiddleware when used in combination withForwardAuth,BasicAuth, orDigestAuth.The middleware matches the regex against the decoded URL path but uses the resulting byte length to slice the percent-encoded raw path. When a dot (or multiple dots) appears in the prefix portion of the URL, the raw path after stripping becomes a dot-segment (e.g.
/./admin/secret).ForwardAuthreceives this dot-segment path inX-Forwarded-Uri, which does not match the protected path patterns and therefore allows the request through. The backend then normalizes the dot-segment to the real path per RFC 3986 and serves the protected contentAn unauthenticated attacker can exploit this against any backend that performs dot-segment normalization.
Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
Summary
StripPrefixRegex uses the byte length of a decoded Path match to slice the encoded RawPath. When percent-encoded characters are in the prefix region, this produces a wrong RawPath. ForwardAuth then
receives this wrong path in X-Forwarded-Uri, sees a path that doesn't match its protection rules, and approves the request. The backend serves protected content.
Details
pkg/middlewares/stripprefixregex/strip_prefix_regex.go, line 62:prefix comes from matching the regex against the decoded req.URL.Path (line 51). len(prefix) is then used to index into the encoded req.URL.RawPath. These lengths don't match when percent-encoding is
present.
Example with regex ^/api:
PoC
Requires Docker and Docker Compose. I have a setup that runs Traefik v3.6.11 with StripPrefixRegex + ForwardAuth + a backend. It sends a normal request (blocked, 403) and an encoded request (bypasses
auth, 200, returns protected data). Can share the files here if useful.
Impact
Auth bypass. Any path protected by ForwardAuth, BasicAuth, or DigestAuth can be accessed without credentials when StripPrefixRegex is in the same middleware chain. The attacker only needs to add a
percent-encoded character to the prefix portion of the URL.
Updated PoC (reporter follow-up)
After further testing, the confirmed working exploit uses
%2e(percent-encoded dot) rather than%20. Dot-segment normalization (/./->/) is RFC 3986 standard behavior handled automatically by Express.js, Go'shttp.ServeMux, Spring Boot, and others — no custom configuration needed.Chain:
Results (Traefik v3.6, unmodified Express.js express.static):
Auth server logs:
Reproduction:
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Traefik Kubernetes CRD allows unauthorized cross-namespace middleware binding
CVE-2026-41174 / GHSA-xhjw-95fp-8vgq
More information
Details
Summary
There is a vulnerability in Traefik's Kubernetes CRD provider cross-namespace isolation enforcement.
When
providers.kubernetesCRD.allowCrossNamespace=false, Traefik correctly rejects direct cross-namespace middleware references fromIngressRouteobjects, but fails to apply the same restriction to middleware references nested inside aChainmiddleware'sspec.chain.middlewares[]. An actor with permission to create or update Traefik CRDs in their own namespace can exploit this to cause Traefik to resolve and apply middleware objects from another namespace, bypassing the documented isolation boundary.Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
Summary
When
providers.kubernetesCRD.allowCrossNamespace=false, Traefik still allows a namespace-localMiddlewareof typeChainto reference middleware objects from another namespace viaspec.chain.middlewares[].namespace.This bypasses the documented cross-namespace restriction and allows an actor with permission to create or update Traefik CRDs in namespace A to bind middleware defined in namespace B to routes in namespace A.
Details
Traefik documents
allowCrossNamespaceas the control that governs whetherIngressRouteobjects may reference resources in other namespaces.Direct middleware references from
IngressRoute.routes[].middlewares[]are validated inpkg/provider/kubernetes/crd/kubernetes_http.gobymakeMiddlewareKeys(...), which rejects cross-namespace references whenallowCrossNamespaceis disabled.However, nested middleware references inside
Middleware.spec.chain.middlewares[]follow a different code path.createChainMiddleware(...)inpkg/provider/kubernetes/crd/kubernetes.godoes not receive or enforceallowCrossNamespace; it resolvesmi.Namespace(or defaults to the current namespace) and appendsmakeID(ns, mi.Name)unconditionally.At runtime,
pkg/server/middleware/middlewares.goqualifies and buildsconfig.Chain.Middlewares, so the cross-namespace middleware is actually loaded and used.This was verified on the current
masterat commit786f7192e11878dfaa634f8263bf79bb730a71cb.This appears related to earlier cross-namespace hardening work, but the surviving issue is a distinct nested
Chainmiddleware code path rather than the already-guarded direct reference path.Expected behavior
When
providers.kubernetesCRD.allowCrossNamespace=false, any middleware reference that resolves to an object in another namespace should be rejected, whether referenced directly from anIngressRouteor indirectly through a localChainmiddleware.Actual behavior
A namespace-local
Chainmiddleware can referencespec.chain.middlewares[].namespacein another namespace, and Traefik resolves and applies that middleware even when cross-namespace references are disabled.Attacker prerequisites
The attacker must have permission to create or update Traefik CRDs in a namespace they control, but does not need permission to modify resources in the target namespace.
PoC
Run Traefik with the Kubernetes CRD provider and set
allowCrossNamespace: false.Create two namespaces, for example
defaultandcross-ns.Apply a middleware in
cross-ns:defaultthat references the middleware above:IngressRouteindefaultthat references only the localmychainmiddleware:Observe that Traefik accepts the configuration and resolves the resulting chain to the middleware from
cross-nseven thoughallowCrossNamespaceis disabled.As a control, replace the local chain reference in the
IngressRoutewith a direct cross-namespace middleware reference. That direct reference is rejected whenallowCrossNamespace=false, which indicates the bypass is specific to nestedChainmiddleware resolution.Impact
This is an authorization / trust-boundary bypass in Traefik's Kubernetes CRD provider.
Clusters that rely on providers.kubernetesCRD.allowCrossNamespace=false for namespace isolation are affected. An actor who is allowed to create or update Traefik CRDs in their own namespace can still cause Traefik to apply middleware from another namespace by referencing it indirectly through a local Chain middleware.
The practical impact depends on which middleware objects exist in the other namespace, but this can allow unauthorized reuse of security-sensitive or policy-bearing middleware across namespace boundaries. Examples include request modification, header manipulation, authentication or forward-auth related behavior, and other traffic-handling policies that were intended to remain namespace-scoped.
Testers have not verified unauthenticated remote compromise, code execution, or universal cross-tenant data exposure. The core issue is that a documented isolation control can be bypassed through the nested Chain middleware reference path.
Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Traefik: A timing side-channel vulnerability allows for valid username enumeration via BasicAuth middleware
CVE-2026-41263 / GHSA-6x2q-h3cr-8j2h
More information
Details
Summary
There is a timing side-channel vulnerability in Traefik's BasicAuth middleware that allows an attacker to enumerate valid usernames through response-time differences.
The variable intended to hold a constant-time fallback secret always resolves to an empty string, causing the constant-time comparison to short-circuit in microseconds rather than performing a full bcrypt evaluation. This restores the original timing oracle and makes it possible to distinguish existing users from non-existing ones by measuring authentication response times.
Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
BasicAuth Timing Regression: CVE-2026-32595 Fix Is a No-Op Due to Map Key/Value Confusion
TL;DR
The patch for CVE-2026-32595 is a no-op. Line 49 of
basic_auth.gohas amap key/value confusion that makes
notFoundSecretalways"". The"constant time" fallback calls
goauth.CheckSecret(password, ""), whichfast-fails in ~1us instead of running bcrypt (~60ms).
Evidence (HEAD
786f7192e, 2026-04-09)Black-box PoC against live traefik binary on port 28080:
Median ratio: 130.4x. Classification: 8/8 correct.
Go in-tree test:
goauth.CheckSecretdirect ratio 12,746x.Root cause (4-step trace)
basic_auth.go:49:users[slices.Collect(maps.Values(users))[0]]-- looksup a hash as a username key, returns
"".basic_auth.go:119-120: callsgoauth.CheckSecret(password, "").go-http-auth/basic.go:87: empty string matches no prefix, falls to defaultcompareMD5HashAndPassword.basic.go:107-109:bytes.SplitN("", "$", 4)returns length 1, functionreturns instantly.
Files
poc/exploit.py-- black-box Python timing oraclepoc/basic_auth_timing_regression_test.go-- Go in-tree testpoc/traefik.yml+poc/dynamic.yml-- traefik configpoc/live_http_poc_output_head.txt-- verbatim PoC output on HEADKoda Reef
Severity
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Traefik's errors middleware forwards Authorization and Cookie headers to separate error page service
CVE-2026-41181 / GHSA-p6hg-qh38-555r
More information
Details
Summary
There is a medium severity information disclosure vulnerability in Traefik's
errors(custom error pages) middleware. When the backend returns a response matching the configured status range, the middleware forwards the original request's complete header set, includingAuthorization,Cookie, and other authentication material, to the separate error page service rather than only the minimal context needed to render the error page. This behavior is undocumented: the documentation states only thatHostis forwarded by default, so operators are not warned that sensitive credentials are shared across service boundaries. Deployments using theerrorsmiddleware with a distinct error page service may inadvertently expose end-user credentials to infrastructure that was not intended to receive them.Patches
For more information
If there are any questions or comments about this advisory, please open an issue.
Original Description
Description
Traefik v3.6.13's supported HTTP
errorsmiddleware discloses sensitive request headers to the configured error page service when the original backend response matches the configured status range and the middleware takes its default header-forwarding path. In the reproduced configuration, the business routeraudit-customerrors@dockerpointed to backend serviceaudit-backend, attached middlewareaudit-leak@docker, and the middleware was configured witherrors.status=500-599,errors.service=audit-error, anderrors.query=/collect. A request to the business route caused the backend to return500, after which Traefik created a secondary request to the error service and copied the originalAuthorizationandCookieheaders into that cross-service request.This is a normal feature path on an ordinary HTTP route. It does not depend on
api.insecure, the dashboard, pprof, or a debug-only mode. The confidentiality boundary that breaks here is the service boundary between the original backend chain and the separate error page service: credentials that were only meant for the original backend are automatically delivered to another service.The root cause is in
pkg/middlewares/customerrors/custom_errors.go:151-160:Unless the
NginxHeadersbranch is explicitly used, the middleware copies the entire original request header map into the error page request. The documentation atdocs/content/reference/routing-configuration/http/middlewares/errorpages.md:103-107only states thatHostis forwarded by default, so operators are not warned thatAuthorization,Cookie, and other authentication material are forwarded as well.Steps To Reproduce
Deploy Traefik v3.6.13 with a normal business route that uses the supported
errorsmiddleware and pointserrors.serviceto a distinct service. The attached PoC usesBASE_URL = "http://127.0.0.1:28080",API_BASE_URL = "http://127.0.0.1:28180",ROUTER_PATH = "/audit-customerrors",AUTHORIZATION = "Bearer audit-secret-token", andCOOKIE = "sessionid=audit-cookie; theme=dark".Start the two attached helper services
customerrors_backend.pyandcustomerrors_error.py. The backend listens on port8000and always returns500. The error service listens on port8000and returns the request method, path, and received headers as JSON. The PoC starts them with the router and middleware labels below so that the business request is handled by the backend, while the error page is fetched from the separate error service:Confirm that Traefik has loaded the route and middleware. The attached
customerrors_router.jsonshows thataudit-customerrors@dockeruses middlewareaudit-leak@docker, and the attachedcustomerrors_middleware.jsonshows that the middleware is enabled withstatus500-599,serviceaudit-error, andquery/collect.Send a request containing sensitive credentials through the business route. The manual reproduction used the following request, and the automated PoC sends the same header values:
500, Traefik internally requests/collectfrom the error service, and the error service receives the originalAuthorizationandCookieheaders. The attachedmanual_curl_customerrors.txtresponse shows the leaked headers directly, and the attachedpoc_customerrors_header_leak.output.txtexecution log shows the same result from the automated PoC.Recommendations
The default behavior should forward only the minimal context needed to render an error page instead of copying the full original header set with
utils.CopyHeaders(pageReq.Header, req.Header). At minimum, Traefik should stripAuthorization,Proxy-Authorization,Cookie,Set-Cookie, and common custom authentication headers such asX-Api-Keybefore issuing the error page request. If operators truly need additional headers, that behavior should be opt-in through an explicit allowlist rather than the default. The documentation should also describe the current behavior and warn that routing an error page to a separate service can otherwise disclose end-user credentials across service boundaries.PoC
The main PoC attachment is
poc_customerrors_header_leak.py.