Summary
Skipper's routesrv-no-auth component: All routesrv API Endpoints Lack Authentication
Description
The routesrv component exposes the full cluster route topology (Ingress/RouteGroup configurations, backend URLs, filter chains, OAuth/OIDC callback paths) and cache-cluster topology (Redis/Valkey shard addresses) over plain HTTP with zero authentication. Any pod in the Kubernetes cluster can reach routesrv via its predictable DNS name and retrieve sensitive cluster-wide routing and cache infrastructure data.
Vulnerable Code
routesrv/routesrv.go:87-99,114-137, all handler registrations on the main mux:
mux.Handle("/routes", b) // eskipBytes.ServeHTTP, all route data
mux.Handle("/routes/{zone}", b) // zone-scoped route data
mux.Handle("/swarm/redis/shards", rh) // Redis cluster addresses
mux.Handle("/swarm/valkey/shards", vh) // Valkey cluster addresses
routesrv/eskipbytes.go:134-196, eskipBytes.ServeHTTP:
func (e *eskipBytes) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
// ... only checks GET/HEAD method, NO auth check
if r.Method != "GET" && r.Method != "HEAD" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
// ... serves all route data immediately
}
routesrv/redishandler.go:28-41, RedisHandler.ServeHTTP:
func (rh *RedisHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
// ... serves Redis cluster addresses immediately, NO auth check
}
routesrv/valkeyhandler.go:28-41, ValkeyHandler.ServeHTTP:
func (vh *ValkeyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
// ... serves Valkey cluster addresses immediately, NO auth check
}
Attack Path
- Initial Compromise: Attacker compromises any pod in the Kubernetes cluster (via application CVE, supply-chain attack, malicious container image, etc.)
- Discovery: Attacker discovers routesrv via predictable Kubernetes DNS name:
skipper-ingress-routesrv.kube-system.svc.cluster.local:9090(documented atdocs/tutorials/operations.md:108,docs/tutorials/ratelimit.md:137,197) - Data Extraction without Auth:
GET http://<routesrv>:9090/routes→ All Ingress/RouteGroup configurations across ALL namespacesGET http://<routesrv>:9090/swarm/redis/shards→ Redis cache cluster node addressesGET http://<routesrv>:9090/swarm/valkey/shards→ Valkey cache cluster node addresses
- Subsequent Attacks: With cache cluster topology, attacker can perform direct cache-level attacks (ratelimit data manipulation, session data exfiltration)
Permission Boundary Analysis
The routesrv uses a ServiceAccount with cluster-wide RBAC to list Ingress (networking.k8s.io), RouteGroup (zalando.org), Endpoints, and Services across all namespaces (see clusterclient.go:648-653 fetchClusterState). The kube-apiserver requires proper ServiceAccount token + RBAC authorization for the Kubernetes API itself, but routesrv exposes the aggregated data over HTTP with zero authentication.
A compromised pod with limited RBAC (restricted to its own namespace) can bypass Kubernetes RBAC entirely by reading routesrv. This crosses the boundary from "namespace-scoped Kubernetes workload with restricted RBAC" to "full cluster route topology across all namespaces".
No NetworkPolicy manifests exist in the deploy/ directory. The default Kubernetes flat network model allows any pod to reach any service, further widening the attack surface.
Exposed Data
| Endpoint | Data Exposed | Impact |
|---|---|---|
GET /routes |
All ingress/routegroup backends: internal service URLs, filter chains (auth, rate limiting, OAuth, JWT, OPA policies), load balancer group membership | Cluster-wide reconnaissance, targeted backend attacks |
GET /routes/{zone} |
Zone-scoped subset of above route data | Same, scoped |
GET /swarm/redis/shards |
Redis cluster internal IP:port pairs | Direct cache-level attacks, ratelimit data manipulation |
GET /swarm/valkey/shards |
Valkey cluster internal IP:port pairs | Same |
Additionally, the data-plane client (eskipfile/remote.go:190-219) also performs plain HTTP GET with no credentials, only an ETag header is sent, confirming that no auth capability exists in the architecture at all.
Mitigation
- Add authentication to all routesrv HTTP endpoints (basic auth, bearer token, mTLS, or shared secret) via flag
-route-server-filters="" - Deploy Kubernetes NetworkPolicies restricting ingress to routesrv to only the data-plane skipper pod selectors
- Consider using mutual TLS authentication between data-plane and control-plane components
NetworkPolicy does not remove the missing-auth condition
Restrictive NetworkPolicies are a valid mitigation, but they are not an application-layer authentication mechanism. The security-relevant defect remains that routesrv serves control-plane-derived data to unauthenticated callers whenever network reachability exists.
Impact framing
This report does not rely on claiming direct integrity or availability impact. The verified issue is a confidentiality-focused control-plane exposure: route definitions, backend topology, filter-chain details, and Redis/Valkey shard addresses become readable to any reachable in-cluster client.
Resources
routesrv/routesrv.go:87-99, handler registration (zero auth)routesrv/eskipbytes.go:134-196, route data handler (no auth)routesrv/redishandler.go:28-41, Redis shard handler (no auth)routesrv/valkeyhandler.go:28-41, Valkey shard handler (no auth)dataclients/kubernetes/clusterclient.go:648-653,fetchClusterState(), shows cluster-wide RBACeskipfile/remote.go:190-219, data-plane client also has no auth capabilitydocs/tutorials/operations.md:108,docs/tutorials/ratelimit.md:137,197, documented routesrv DNS name
Impact
A critical operation is accessible without requiring any authentication. Typical impact: any user can invoke the privileged function.
CVE-2026-54246 has a CVSS score of 5.7 (Medium). The vector is reachable from an adjacent network, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (0.27.13); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2026-54246? CVE-2026-54246 is a medium-severity missing authentication for critical function vulnerability in github.com/zalando/skipper (go), affecting versions < 0.27.13. It is fixed in 0.27.13. A critical operation is accessible without requiring any authentication.
- How severe is CVE-2026-54246? CVE-2026-54246 has a CVSS score of 5.7 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of github.com/zalando/skipper are affected by CVE-2026-54246? github.com/zalando/skipper (go) versions < 0.27.13 is affected.
- Is there a fix for CVE-2026-54246? Yes. CVE-2026-54246 is fixed in 0.27.13. Upgrade to this version or later.
- Is CVE-2026-54246 exploitable, and should I be worried? Whether CVE-2026-54246 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-54246 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-54246? Upgrade
github.com/zalando/skipperto 0.27.13 or later.