CVE-2026-54246: Medium severity go/github.com/zalando/skipper vulnerability

Published Jul 17, 2026
·
Updated

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: go 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: go 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: go 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: go 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

1. Initial Compromise: Attacker compromises any pod in the Kubernetes cluster (via application CVE, supply-chain attack, malicious container image, etc.) 2. Discovery: Attacker discovers routesrv via predictable Kubernetes DNS name: skipper-ingress-routesrv.kube-system.svc.cluster.local:9090 (documented at docs/tutorials/operations.md:108, docs/tutorials/ratelimit.md:137,197) 3. Data Extraction without Auth: - GET http://<routesrv>:9090/routes → All Ingress/RouteGroup configurations across ALL namespaces - GET http://<routesrv>:9090/swarm/redis/shards → Redis cache cluster node addresses - GET http://<routesrv>:9090/swarm/valkey/shards → Valkey cache cluster node addresses 4. 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

1. Add authentication to all routesrv HTTP endpoints (basic auth, bearer token, mTLS, or shared secret) via flag -route-server-filters="" 2. Deploy Kubernetes NetworkPolicies restricting ingress to routesrv to only the data-plane skipper pod selectors 3. 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 RBAC - eskipfile/remote.go:190-219 — data-plane client also has no auth capability - docs/tutorials/operations.md:108, docs/tutorials/ratelimit.md:137,197 — documented routesrv DNS name

Affected Software

1 affected componentFixes available
go/github.com/zalando/skipper<0.27.13
0.27.13

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade go/github.com/zalando/skipper to a version that resolves this vulnerability.

    Fixed in 0.27.13
  2. Configuration

    Enable authentication/route-server filters on routesrv by setting flag -route-server-filters="" (instead of empty/no authentication) so that all HTTP endpoints guarded by this filter mechanism require credentials (basic/bearer/mTLS/shared secret) to access /routes, /swarm/redis/shards, and /swarm/valkey/shards.

    routesrv -route-server-filters
  3. Compensating control

    Add Kubernetes NetworkPolicies for the routesrv service to restrict ingress so only the intended data-plane skipper pod selectors can reach routesrv (no NetworkPolicy manifests exist in deploy/ per the material).

  4. Compensating control

    Use mutual TLS authentication between data-plane and control-plane components so that only authenticated components can query routesrv over HTTP endpoints.

Event History

Jul 17, 2026
Advisory Published
via GitHub·09:46 PM
Data Sourced
via GitHub·09:46 PM
DescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-54246?

The severity of CVE-2026-54246 is medium with a score of 5.7.

2

What type of access does CVE-2026-54246 expose?

CVE-2026-54246 exposes cluster route topology and cache-cluster topology over plain HTTP with zero authentication.

3

How can I mitigate CVE-2026-54246?

To mitigate CVE-2026-54246, implement proper authentication measures for the routesrv component.

4

Which software is affected by CVE-2026-54246?

CVE-2026-54246 affects the Zalando Skipper software, specifically the routesrv component.

5

When was CVE-2026-54246 published?

CVE-2026-54246 was published on July 17, 2026.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203