CVE-2026-53714 Overview
CVE-2026-53714 is a missing authentication vulnerability [CWE-306] in Envoy Gateway, an open source project for managing Envoy Proxy as a standalone or Kubernetes-based application gateway. The flaw affects deployments configured with provider.kubernetes.deploy.type=GatewayNamespace. In this mode, the xDS gRPC server installs a JWT StreamInterceptor but omits a UnaryInterceptor, leaving every unary Fetch RPC unauthenticated. The streaming interceptor also authenticates only discoveryv3.DeltaDiscoveryRequest messages, failing open for discoveryv3.DiscoveryRequest used by the State-of-the-World protocol. Any pod that can reach port 18000 can retrieve TLS private keys, xDS resources, backend endpoints, and routing configuration. The issue is fixed in versions 1.7.4 and 1.8.1.
Critical Impact
Unauthenticated adjacent-network attackers can extract TLS private keys and full xDS routing configuration from Envoy Gateway deployments running in GatewayNamespaceMode.
Affected Products
- Envoy Gateway versions prior to 1.7.4 (1.7.x branch)
- Envoy Gateway versions prior to 1.8.1 (1.8.x branch)
- Deployments configured with provider.kubernetes.deploy.type=GatewayNamespace
Discovery Timeline
- 2026-09-14 - CVE-2026-53714 published to NVD
- 2026-09-15 - Last updated in NVD database
Technical Details for CVE-2026-53714
Vulnerability Analysis
Envoy Gateway exposes an xDS gRPC service on port 18000 that distributes configuration to Envoy proxy instances. In GatewayNamespaceMode, the server relies on Kubernetes JWT authentication enforced through a gRPC interceptor. The interceptor implementation contains two independent authentication gaps.
First, only a StreamInterceptor is registered, so unary Fetch RPCs bypass authentication entirely. Second, the streaming interceptor performs a Go type assertion for discoveryv3.DeltaDiscoveryRequest. When a client sends discoveryv3.DiscoveryRequest messages, used by the State-of-the-World xDS protocol variant, the type assertion fails and the interceptor returns success without validating the JWT.
An attacker with network reachability to the xDS port can invoke StreamSecrets to exfiltrate TLS private keys, StreamAggregatedResources to retrieve all xDS resources, StreamClusters and StreamEndpoints to enumerate backend services, and StreamRoutes or StreamListeners to map routing configuration.
Root Cause
The root cause is an incomplete authentication enforcement design [CWE-306]. The gRPC server registration in internal/xds/runner/runner.go attached only jwtInterceptor.Stream(), and the interceptor logic in internal/xds/server/kubejwt/jwtinterceptor.go gated JWT validation behind a narrow message type check that silently succeeded for unmatched request types.
Attack Vector
Exploitation requires network access to TCP port 18000 of the Envoy Gateway pod. Any workload running in the same cluster network, including compromised sidecar containers or malicious pods scheduled to a shared namespace, can issue crafted gRPC requests. No credentials, tokens, or user interaction are required.
// Patch: register the missing UnaryInterceptor alongside StreamInterceptor
// Source: https://github.com/envoyproxy/gateway/commit/f1f9829af2a231f0cae915c09800353c76622d97
grpcOpts = append(grpcOpts,
grpc.Creds(creds),
grpc.StreamInterceptor(jwtInterceptor.Stream()),
grpc.UnaryInterceptor(jwtInterceptor.Unary()),
)
The patch to jwtinterceptor.go replaces the type-gated RecvMsg wrapper with an explicit authenticate function that extracts the node ID, requires the authorization metadata header, and validates the bearer token against the Kubernetes token review API for every message type:
// Source: https://github.com/envoyproxy/gateway/commit/f1f9829af2a231f0cae915c09800353c76622d97
func (i *JWTAuthInterceptor) authenticate(ctx context.Context, msg any) error {
nodeID, err := extractNodeID(msg)
if err != nil {
return err
}
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return fmt.Errorf("missing metadata")
}
authHeader := md.Get("authorization")
if len(authHeader) == 0 {
return fmt.Errorf("missing authorization token in metadata: %s", md)
}
token := strings.TrimPrefix(authHeader[0], "Bearer ")
if err := i.validateKubeJWT(ctx, token, nodeID); err != nil {
i.logger.Error(err, "failed to validate token")
return fmt.Errorf("failed to validate token: %w", err)
}
return nil
}
Detection Methods for CVE-2026-53714
Indicators of Compromise
- Unexpected gRPC connections to Envoy Gateway pods on TCP port 18000 originating from workloads outside the intended Envoy data plane.
- xDS requests such as StreamSecrets, StreamAggregatedResources, or Fetch unary RPCs lacking a valid authorization metadata header.
- gRPC requests using discoveryv3.DiscoveryRequest messages when only Envoy proxies using DeltaDiscoveryRequest are expected.
Detection Strategies
- Enable audit logging on the xDS server and alert on any successful StreamSecrets response served to a client that did not present a validated JWT.
- Use Kubernetes NetworkPolicy telemetry or a service mesh to identify pods initiating connections to the Envoy Gateway control plane port 18000.
- Correlate Kubernetes TokenReview API activity with xDS session establishment; the absence of TokenReviews preceding an xDS session indicates unauthenticated access.
Monitoring Recommendations
- Monitor Envoy Gateway logs for warnings or errors from the kubejwt package and for anomalous xDS resource enumeration volume.
- Track east-west traffic to the Envoy Gateway namespace and baseline expected client identities.
- Alert on pod creations in namespaces that have network reachability to the xDS port but do not require it.
How to Mitigate CVE-2026-53714
Immediate Actions Required
- Upgrade Envoy Gateway to version 1.7.4 or 1.8.1 on all clusters using GatewayNamespaceMode.
- Rotate all TLS private keys and secrets that were served through the xDS StreamSecrets API, as they must be considered compromised if the vulnerable version was exposed.
- Restrict network access to the xDS gRPC port 18000 using Kubernetes NetworkPolicy limited to the intended Envoy proxy pods.
Patch Information
The fix is delivered in Envoy Gateway v1.7.4 and Envoy Gateway v1.8.1. The patch adds a UnaryInterceptor and replaces the type-gated stream authentication with a message-type-agnostic authenticate function. Full technical detail is available in the GitHub Security Advisory GHSA-22xc-xg2r-9j7v and the merged fix PR #8986.
Workarounds
- If immediate upgrade is not possible, switch away from provider.kubernetes.deploy.type=GatewayNamespace to a deployment mode not affected by the interceptor gap.
- Enforce strict NetworkPolicy rules so only known Envoy data plane pods can reach TCP port 18000 on Envoy Gateway.
- Use a service mesh mTLS policy to require peer authentication in front of the xDS listener where feasible.
# Example Kubernetes NetworkPolicy limiting xDS access to Envoy proxy pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: restrict-xds-access
namespace: envoy-gateway-system
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: envoy-gateway
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/component: envoy-proxy
ports:
- protocol: TCP
port: 18000
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.
