← Back to Feed CACHED · 2026-09-20 06:23:50 · CACHE_KEY CVE-2026-84303
CVE-2026-84303 · CWE-178 · Disclosed 2026-09-01

gRPC-Go is the Go language implementation of gRPC.

ASSESSED — NOISGATE
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A bouncer checking IDs with the wrong font case lets everyone through the VIP rope

CVE-2026-84303 is an authorization-bypass flaw in gRPC-Go's xDS RBAC HTTP filter (internal/xds/httpfilter/rbac/rbac.go). The normalizeHeaderMatcher function does not lowercase header names before evaluation, but HTTP/2 metadata keys arrive lowercase per spec. Any DENY policy referencing a mixed-case header — e.g., X-Role, User-Agent, Content-Type — silently fails to match, causing the policy to fail open. A secondary issue allows reserved grpc- prefixed headers (blocked by gRFC A41) to be injected via casing tricks like Grpc-Status. All versions of google.golang.org/grpc prior to v1.83.1 are affected.

The GitLab Advisory Database tags this MEDIUM at CVSS 6.5. That score is defensible for the *narrow population* that actually runs xDS RBAC, but the advisory doesn't call out how niche the feature is. The vast majority of gRPC-Go deployments use standard interceptors or gateway-level auth — they never load the xDS RBAC HTTP filter at all. For those shops, this CVE is a no-op. For the subset running proxyless gRPC mesh with Istio or Traffic Director and relying on xDS-pushed RBAC policies, the impact is real: authorization rules silently stop working. We assess at 5.5 MEDIUM — meaningful where it hits, but the hit surface is small.

"xDS RBAC header-case mismatch fails DENY rules open, but only matters in proxyless mesh"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Target runs gRPC-Go with xDS RBAC

The gRPC server must be bootstrapped via xds.NewGRPCServer() and receive RBAC HTTP filter configuration from an xDS control plane (e.g., Istio istiod, Google Traffic Director). Without xDS RBAC, the vulnerable code path is never executed.
Conditions required:
  • Target application imports google.golang.org/grpc/xds and uses xds.NewGRPCServer()
  • xDS control plane pushes RBAC HTTP filter config to the server
Where this breaks in practice:
  • Most gRPC-Go services use standard grpc.NewServer() with interceptor-based auth — xDS RBAC is a niche proxyless-mesh feature
  • GRPC_XDS_EXPERIMENTAL_RBAC env var must not be set to false
STEP 02

DENY policy references mixed-case headers

The xDS RBAC policy pushed by the control plane must include a DENY rule with a header matcher using mixed-case characters (e.g., X-Role instead of x-role). Since HTTP/2 mandates lowercase headers and the filter does not normalize, the matcher will never match incoming metadata.
Conditions required:
  • At least one DENY rule references a header name containing uppercase characters
  • The policy was authored with conventional mixed-case HTTP header names
Where this breaks in practice:
  • Some policy generators (e.g., Istio AuthorizationPolicy) may already lowercase header names before pushing xDS config
  • Operators who test their DENY rules would notice the silent failure
Detection/coverage: Audit xDS RBAC config dump via grpcurl admin endpoint or Istio istioctl proxy-config for mixed-case header matchers
STEP 03

Attacker sends normal gRPC request

No special crafting is required. The attacker sends an ordinary gRPC request carrying the header value that should trigger the DENY rule. Because the rule's mixed-case header name doesn't match the lowercase incoming metadata key, the DENY never fires. The request is served as if no DENY policy existed.
Conditions required:
  • Network access to the gRPC service endpoint
Where this breaks in practice:
  • Service may sit behind a mesh sidecar, L7 gateway, or network policy that independently enforces authorization
  • mTLS or other transport-level controls may restrict who can connect
Detection/coverage: No scanner specifically tests for this; manual validation required by comparing RBAC config against gRPC-Go version
STEP 04

Authorization bypass achieved

The attacker accesses resources or RPCs that should have been blocked by the DENY policy. The scope is limited to whatever the failed DENY rule was protecting — it does not escalate beyond the service's own authorization boundary. The gRFC A41 bypass additionally allows injecting reserved grpc- prefixed metadata (e.g., Grpc-Status) which could confuse downstream processing.
Conditions required:
  • Successful bypass of step 3
Where this breaks in practice:
  • Application-layer authorization checks (business logic, JWT validation in interceptors) still apply independently of xDS RBAC
  • Impact is bounded to the single service, not lateral movement
Detection/coverage: Look for unexpected access patterns in gRPC audit logs; the bypassed DENY rule leaves no trace in RBAC decision logs
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo evidence. Not listed in CISA KEV. No GreyNoise or Shadowserver observations. No threat-actor campaigns reported as of 2026-09-20.
Proof-of-ConceptNone public. No PoC repos found on GitHub or ExploitDB. Exploitation is trivial in concept (send a normal request) but requires a specific server-side misconfiguration to be impactful.
EPSS Score0.00311 (~bottom 30th percentile). FIRST model rates exploitation probability in next 30 days as negligible.
KEV StatusNot listed. No CISA KEV entry as of 2026-09-20.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N — Network-accessible, no privileges or interaction needed, but impact limited to low confidentiality and integrity. No availability impact.
Affected VersionsAll versions of google.golang.org/grpc < v1.83.1. The vulnerable function is in internal/xds/httpfilter/rbac/rbac.go.
Fixed Versionv1.83.1 (released ~Aug 19, 2026). Also addressed in v1.83.2 alongside sibling advisories GHSA-2v4p-qf9q-27wj and GHSA-vp52-pcj8-j9qc.
Exposure SurfacegRPC-Go is an extremely popular Go module, but the xDS RBAC HTTP filter is only loaded by services using xds.NewGRPCServer() in proxyless mesh configurations (Istio, Traffic Director, custom xDS control planes). Estimated <5% of gRPC-Go installations use this feature.
Disclosure Date2026-09-01 (CVE published). GitHub advisory GHSA-qc2q-p7wx-3px3 published 2026-08-19.
ReporterNot publicly attributed. Filed via gRPC-Go GitHub security advisory process.
04 · The Call

Final Verdict
= UNCHANGED to MEDIUM (5.5/10)

Why this verdict

  • Narrow feature surface: The vulnerability only affects gRPC-Go servers using the xDS RBAC HTTP filter via xds.NewGRPCServer(). This is a proxyless-mesh feature used by a small fraction (<5%) of the gRPC-Go installed base. Standard grpc.NewServer() deployments are completely unaffected.
  • Policy-configuration-dependent: Even within xDS RBAC users, exploitation requires DENY rules that reference mixed-case header names. If the control plane (e.g., Istio) lowercases header names before pushing config, the vulnerability is not reachable.
  • No attacker sophistication required, but no RCE either: The attacker simply sends a normal gRPC request — no payload crafting needed. However, the impact ceiling is authorization bypass on a single service, not code execution, lateral movement, or privilege escalation.
  • No active exploitation or PoC: EPSS 0.00311, not KEV-listed, no public PoC, no observed campaigns. The threat is entirely theoretical as of September 2026.
  • Role multiplier: gRPC-Go with xDS RBAC is deployed in (a) *Kubernetes microservices* using proxyless mesh — typical role, blast radius is service-level auth bypass; (b) *API gateways or ingress services* — higher-value but these typically have redundant auth layers (JWT, mTLS, gateway WAF); (c) *orchestration control planes* — rare, and control plane services typically use interceptor-based auth, not xDS RBAC. No high-value role produces domain takeover, fleet compromise, or supply-chain pivot from this bug alone. The floor does not trigger.

Why not higher?

Promoting to HIGH would require either active exploitation, a broader blast radius, or a path to code execution. This CVE delivers authorization bypass on a single service within a niche deployment pattern (proxyless xDS mesh). The attacker gains access to one service's protected RPCs — not domain admin, not fleet-wide impact, not persistent access. Redundant auth layers (mTLS, JWT interceptors, gateway policies) independently block the same traffic in most real architectures.

Why not lower?

Dropping to LOW would undervalue the silent-fail-open nature of this bug. When it does hit, DENY rules stop working with zero indication — no error, no log, no alert. An operator who wrote an RBAC policy and tested it with a sidecar proxy might never discover the proxyless path ignores it. The CVSS vector's AV:N/PR:N/UI:N combination means any network-reachable attacker benefits, and the CWE-863 classification (Incorrect Authorization) is architecturally serious even if scoped.

05 · Compensating Control

What to do — in priority order.

  1. Upgrade google.golang.org/grpc to v1.83.1 or later — The definitive fix. Update your go.mod dependency and rebuild. Per the noisgate MEDIUM remediation SLA, deploy within 365 days — but if you actively use xDS RBAC with mixed-case header DENY rules, treat this as urgent and patch within days.
  2. Audit xDS RBAC policies for mixed-case header matchers — Run istioctl proxy-config listener <pod> -o json or dump the xDS config from your control plane. Search for headerMatcher entries with uppercase characters. Rewrite them to all-lowercase as a stopgap. No mitigation SLA applies for MEDIUM, but this is a 15-minute config fix.
  3. Layer interceptor-based authorization independently of xDS RBAC — Add a gRPC unary/stream interceptor that performs authorization checks (JWT validation, service-account verification) so that xDS RBAC is not your sole enforcement point. Defense-in-depth ensures this class of filter bypass cannot silently degrade your security posture.
  4. Enable gRPC audit logging for RBAC decisions — If your xDS control plane supports it, enable RBAC audit logging to detect when DENY rules are not matching expected traffic. This provides detection coverage while you plan the upgrade.
What doesn't work
  • WAF rules — Web Application Firewalls operate at HTTP/1.1 or HTTP/2 frame level and do not inspect gRPC xDS RBAC policy evaluation logic. A WAF cannot compensate for a server-side policy-matching bug.
  • Network segmentation alone — While limiting who can reach the gRPC port reduces exposure, it does not fix the silent DENY-rule failure. Authorized internal callers who should be denied specific RPCs will still bypass the policy.
  • Upgrading Istio without upgrading grpc-go — If you run proxyless gRPC (no sidecar), the RBAC evaluation happens inside the Go binary. Upgrading your Istio control plane does not fix the client-side library bug.
06 · Verification

Crowdsourced verification payload.

Run on any host or CI runner that has the Go project source tree. Requires read access to go.mod and go.sum. No root privileges needed. Example: bash check_cve_2026_84303.sh /path/to/your/go/project

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash\n# CVE-2026-84303 Checker - gRPC-Go xDS RBAC Header Case Bypass\n# Outputs: VULNERABLE / PATCHED / UNKNOWN\nset -euo pipefail\n\nTARGET_DIR=\"${1:-.}\"\nFIXED=\"1.83.1\"\n\nif [ ! -f \"$TARGET_DIR/go.mod\" ]; then\n  echo \"UNKNOWN - no go.mod found in $TARGET_DIR\"\n  exit 2\nfi\n\n# Check go.sum for the resolved version (handles replace directives)\nif [ -f \"$TARGET_DIR/go.sum\" ]; then\n  VER=$(grep -oP 'google\\.golang\\.org/grpc v\\K[0-9]+\\.[0-9]+\\.[0-9]+' \"$TARGET_DIR/go.sum\" | sort -V | tail -1)\nfi\n\n# Fallback to go.mod\nif [ -z \"${VER:-}\" ]; then\n  VER=$(grep -oP 'google\\.golang\\.org/grpc v\\K[0-9]+\\.[0-9]+\\.[0-9]+' \"$TARGET_DIR/go.mod\" | head -1)\nfi\n\nif [ -z \"${VER:-}\" ]; then\n  echo \"UNKNOWN - google.golang.org/grpc not found in go.mod or go.sum\"\n  exit 2\nfi\n\n# Also check if xDS RBAC is actually imported\nXDS_USED=\"no\"\nif grep -rq 'google.golang.org/grpc/xds' \"$TARGET_DIR/\" --include='*.go' 2>/dev/null; then\n  XDS_USED=\"yes\"\nfi\n\n# Version comparison\nif printf '%s\\n%s' \"$FIXED\" \"$VER\" | sort -V -C; then\n  echo \"PATCHED - grpc-go v$VER >= v$FIXED (xDS import detected: $XDS_USED)\"\n  exit 0\nelse\n  if [ \"$XDS_USED\" = \"yes\" ]; then\n    echo \"VULNERABLE - grpc-go v$VER < v$FIXED AND xDS package imported\"\n    exit 1\n  else\n    echo \"VULNERABLE - grpc-go v$VER < v$FIXED (xDS not imported - likely not exploitable)\"\n    exit 1\n  fi\nfi
07 · Sources

Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.