
Proof-of-concept demonstrating an authorization bypass in Traefik's Kubernetes Gateway provider (CVE-2026-54761) via a crossProviderNamespaces vulnerability, exposing internal services like api@internal.
This repository contains a local Proof of Concept (PoC) for CVE-2026-54761, a high severity vulnerability in Traefik's Kubernetes Gateway provider.
The vulnerability affects the crossProviderNamespaces allowlist. For HTTPRoute rules that declare multiple weighted backend references, Traefik validates the allowlist against the target backendRef.namespace instead of the route's own namespace. As a result, an HTTPRoute in a namespace that is not allow-listed can expose internal Traefik services such as api@internal when the backend reference points at an allow-listed namespace and a matching Gateway API ReferenceGrant exists.
Reported by: saku0512 (https://github.com/Saku0512), vvvvvvvvvvel (https://github.com/vvvvvvvvvvel)
This project is for educational and authorized security testing purposes only.
Do not run this against systems you do not own or administer. The PoC is designed to create a disposable local kind cluster and demonstrate the issue in an isolated environment.
api@internal can be exposed through the normal data planeThe crossProviderNamespaces option is intended to restrict which Gateway API route namespaces may declare TraefikService backend references, including references to @internal services.
In the vulnerable weighted-backend path, Traefik checks the allowlist against backendRef.namespace. This is incorrect because the security boundary is the namespace of the HTTPRoute that declares the reference.
Expected behavior:
providers:
kubernetesGateway:
crossProviderNamespaces:
- trusted
Only routes whose own namespace is trusted should be allowed to declare cross-provider TraefikService backend references.
Vulnerable behavior:
backendRefs:
- group: traefik.io
kind: TraefikService
name: api@internal
namespace: trusted
An HTTPRoute in the attacker namespace can be accepted when the route has multiple backend references and the backendRef.namespace is set to the allow-listed trusted namespace.
The PoC creates a disposable local kind cluster with:
providers.kubernetesGateway.crossProviderNamespaces=trustedReferenceGrant from trustedcd external-repro-kind
./run-kind-repro.sh
The script deletes the cluster automatically when it exits.
To keep the cluster for manual inspection:
KEEP_CLUSTER=1 ./run-kind-repro.sh
The control route uses a single forbidden api@internal backend reference from the attacker namespace. It should not expose the API:
control status: 404
The exploit route uses two backend references, causing Traefik to build a weighted service. On vulnerable versions, the request to /api/http/services returns Traefik API JSON:
exploit returned Traefik API JSON
api@internal status: enabled
weighted members:
api@internal 1000000
attacker-whoami-http-80 1
The important difference is that both routes are created from the same untrusted attacker namespace. The single-backend control is rejected, but the mixed weighted-backend route resolves successfully and exposes api@internal.
external-repro-kind/kind-config.yaml - local kind cluster with Traefik exposed on 127.0.0.1:18080external-repro-kind/traefik-v371.yaml - vulnerable Traefik deployment and GatewayClassexternal-repro-kind/gateway-exploit.yaml - namespaces, Gateway, ReferenceGrant, control route, and bypass routeexternal-repro-kind/run-kind-repro.sh - end-to-end local reproducerUpgrade Traefik to a fixed version:
Operators should also review existing Gateway API ReferenceGrant resources and avoid granting untrusted namespaces access to cross-provider TraefikService references unless that delegation is explicitly intended.