{"id":"GHSA-gg5j-6742-v827","summary":"@grpc/grpc-js: RBAC override configs in VirtualHost and Route resources are not applied","details":"### Summary\n\n`XdsServer` in `@grpc/grpc-js-xds` does not apply `RBACPerRoute` overrides from matching Route or VirtualHost resources. When a trusted xDS control plane supplies a broad top-level ALLOW policy and a stricter override, `XdsServer` ACKs the resources but evaluates the RPC under the top-level policy.\n\n### Details\n\n### Override parser lookup uses the override message type\n\n`parseOverrideFilterConfig()` in packages/grpc-js-xds/src/http-filter.ts:225-257 looks up FILTER_REGISTRY using the override message type:\n\n`type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute`\nSource: https://github.com/grpc/grpc-node/blob/56567d9604b4e45cdca0d2e3c2a60ac227ee659d/packages/grpc-js-xds/src/http-filter.ts#L225-L257\n\n`setup()` in packages/grpc-js-xds/src/http-filter/rbac-filter.ts:167-173 registers the filter only under the top-level RBAC type:\n\n`type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC`\nSource: https://github.com/grpc/grpc-node/blob/56567d9604b4e45cdca0d2e3c2a60ac227ee659d/packages/grpc-js-xds/src/http-filter/rbac-filter.ts#L167-L173\n\nThe lookup returns null even though the registered entry contains `parseOverrideRbacConfig()`, and server.ts silently skips the override.\n\n### Override maps are keyed by type URL instead of filter name\n\n`overrideConfigMaps` in server.ts:99-102 is documented as keyed by HTTP filter name, but server.ts:169-174 stores each map under `filterConfig.typeUrl`.\n\nSource: https://github.com/grpc/grpc-node/blob/56567d9604b4e45cdca0d2e3c2a60ac227ee659d/packages/grpc-js-xds/src/server.ts#L99-L102\n\nSource: https://github.com/grpc/grpc-node/blob/56567d9604b4e45cdca0d2e3c2a60ac227ee659d/packages/grpc-js-xds/src/server.ts#L169-L174\n\nRoute overrides are later looked up by their `typed_per_filter_config` key, which is the `HttpFilter.name`. An ordinary key such as rbac therefore misses the stored map.\n\n### VirtualHost overrides are not read\n\n`handleRouteConfigurationResource()` in server.ts:225-249 reads `route.typed_per_filter_config` but never reads `virtualHost.typed_per_filter_config`.\n\nSource: https://github.com/grpc/grpc-node/blob/56567d9604b4e45cdca0d2e3c2a60ac227ee659d/packages/grpc-js-xds/src/server.ts#L225-L249\n\nWhen no override reaches the RBAC interceptor, rbac-filter.ts:125-155 evaluates the broader top-level policy.\n\n### Proof of concept\n\nSet:\n```\nGRPC_XDS_EXPERIMENTAL_RBAC=true\n```\n\nRun `XdsServer` with a protected unary handler.\n\nHave the ADS control plane deliver a Listener containing an RBAC HTTP filter named rbac with a top-level ALLOW-any policy:\n\n```\nname: rbac\ntyped_config:\n  \"@type\": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC\n  rules:\n    action: ALLOW\n    policies:\n      allow-any:\n        principals: [{ any: true }]\n        permissions: [{ any: true }]\n```\n\nDeliver a matching non-forwarding route with this override:\n\n```\ntyped_per_filter_config:\n  rbac:\n    \"@type\": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute\n    rbac:\n      rules:\n        action: DENY\n        policies:\n          deny-any:\n            principals: [{ any: true }]\n            permissions: [{ any: true }]\n```\n\nInvoke the protected unary method without credentials.\n\nExpected: The route-specific DENY policy rejects the RPC before the protected handler runs.\n\nObserved: `XdsServer` ACKs the resources, retains the top-level ALLOW policy, and runs the protected handler.\n\n```\nListener and RouteConfiguration: ACKED\ngRPC status: OK\nhandler invocations: 1\nresponse: PROTECTED_SECRET_RECORD_RBAC_OVERRIDE\n```\n\n### Impact\n\nUsers of `@grpc/grpc-js-xds` who are using RBAC-based authentication with override configurations may unintentionally accept some requests that should be rejected.","aliases":["CVE-2026-128065"],"modified":"2026-11-12T23:15:03.078298996Z","published":"2026-11-12T22:55:47Z","database_specific":{"github_reviewed_at":"2026-11-12T22:55:47Z","nvd_published_at":null,"cwe_ids":["CWE-863"],"severity":"MODERATE","github_reviewed":true},"references":[{"type":"WEB","url":"https://github.com/grpc/grpc-node/security/advisories/GHSA-gg5j-6742-v827"},{"type":"WEB","url":"https://github.com/grpc/grpc-node/commit/b8f3ced4d4699338dd33dc0f7b1d68d689a31d0e"},{"type":"PACKAGE","url":"https://github.com/grpc/grpc-node"},{"type":"WEB","url":"https://github.com/grpc/grpc-node/releases/tag/@grpc/grpc-js-xds@1.14.2"}],"affected":[{"package":{"name":"@grpc/grpc-js-xds","ecosystem":"npm","purl":"pkg:npm/%40grpc/grpc-js-xds"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.14.0"},{"fixed":"1.14.2"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-gg5j-6742-v827/GHSA-gg5j-6742-v827.json"}}],"schema_version":"1.9.2","severity":[{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N"}]}