GHSA-5587-2x54-jj6h: 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: ```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 s
GHSA-5587-2x54-jj6h: Skipper's routesrv-no-auth component: All routesrv API Endpoints Lack Authentication
Description
## 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 s
CVSS v3.1
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
Weaknesses
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-5587-2x54-jj6h
- Osv Schema Version
- 1.4.0
- Aliases
- ["CVE-2026-54246"]
- Ecosystems
- ["Go"]
- Database Specific Severity
- MODERATE
- Cvss Version
- 3.1
Threat ID: 6a5b60962d1edb114c84a5ea
Added to database: 07/18/2026, 11:16:38 UTC
Last updated: 07/18/2026, 12:46:22 UTC
Views: 4
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.