Open Redirect
Description
The Open Redirect vulnerability arises when the dashboard redirection logic uses the X-Forwarded-Prefix header to compose the redirect location without validating that the value is a relative path. An attacker could set X-Forwarded-Prefix to an absolute URL (including host and/or scheme) to redirect users to an external domain. The commit adds a validation check that rejects absolute URLs and resets to empty, preventing external redirects via this header.
Proof of Concept
Proof-of-concept (pre-fix exploit):
Assume an attacker can reach the Traefik dashboard at http://traefik.example/dashboard/ and the dashboard redirects to the value of X-Forwarded-Prefix to build the final redirect URL.
1) Attacker sends a crafted request to trigger a redirect:
curl -i -H "X-Forwarded-Prefix: https://evil.example/steal" http://traefik.example/dashboard/
Expected vulnerable behavior (pre-fix): The server uses the header value directly as the redirect target, resulting in a 302 redirect to https://evil.example/steal, enabling an open redirect.
2) After applying the fix (the commit in question):
The validator rejects the absolute URL (host or scheme present) and resets xfPrefix to empty, causing the server to redirect to an internal default path instead of an external site.
Note: The actual redirect target depends on the internal routing; the key point is that external domains can no longer be specified via X-Forwarded-Prefix.
Commit Details
Author: Kevin Pollet
Date: 2026-07-07 08:32 UTC
Message:
Fix X-Forwarded-Prefix documentation for dashboard redirection
Triage Assessment
Vulnerability Type: Open Redirect
Confidence: HIGH
Reasoning:
The change validates the X-Forwarded-Prefix header to prevent absolute URLs (host or scheme) from being used in dashboard redirection. This mitigates open redirect risks and ensures redirects stay within the trusted prefix, addressing a potential input validation vulnerability around redirect targets.
Verification Assessment
Vulnerability Type: Open Redirect
Confidence: HIGH
Affected Versions: <= 3.7.0-ea.3
Code Diff
diff --git a/pkg/api/dashboard/dashboard.go b/pkg/api/dashboard/dashboard.go
index d5c5c10129b..86805c5f253 100644
--- a/pkg/api/dashboard/dashboard.go
+++ b/pkg/api/dashboard/dashboard.go
@@ -82,7 +82,15 @@ func Append(router *mux.Router, basePath string, customAssets fs.FS) error {
HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
xfPrefix := req.Header.Get("X-Forwarded-Prefix")
- // Validates that the X-Forwarded-Prefix value contains a relative URL.
+ // X-Forwarded-Prefix is a trusted header: the upstream hop is
+ // responsible for setting a valid, sanitized value and stripping
+ // any value coming from an untrusted client.
+ //
+ // The check below only rejects an obviously absolute URL (carrying a Host or
+ // Scheme). It is intentionally not an exhaustive validator: values a browser
+ // may later re-interpret as cross-origin (e.g. backslash sequences like
+ // "\\foo.com", normalised to "//foo.com" per the WHATWG URL spec) are the
+ // trusted upstream's responsibility.
if u, err := url.Parse(xfPrefix); err != nil || u.Host != "" || u.Scheme != "" {
log.Error().Msgf("X-Forwarded-Prefix contains an invalid value: %s, defaulting to empty prefix", xfPrefix)
xfPrefix = ""