← Back to Feed CACHED · 2026-09-09 17:38:29 · CACHE_KEY CVE-2026-33186
CVE-2026-33186 · CWE-285 · Disclosed 2026-03-20

gRPC-Go is the Go language implementation of gRPC.

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

Like a bouncer who checks IDs by last name only — drop the first letter and you walk right past the velvet rope

CVE-2026-33186 is an authorization bypass in google.golang.org/grpc versions prior to v1.79.3. The gRPC-Go HTTP/2 server transport stored the raw :path pseudo-header value without validating its leading slash. The routing layer internally normalized paths for dispatch, but authorization interceptors — including the official grpc/authz RBAC engine (authz.NewStatic(), authz.NewFileWatcher()) and any custom interceptor reading info.FullMethod or grpc.Method(ctx) — evaluated the *raw, pre-normalization* string. An attacker sending Service/Method instead of /Service/Method caused deny rules to fail string matching, falling through to a permissive default-allow policy. The result: complete bypass of path-based RBAC deny rules with a single missing character.

The vendor CVSS of 9.1 CRITICAL (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N) models a universally exploitable, unauthenticated network attack — and the attack *is* trivially easy when the preconditions are met. But the score overstates real-world exposure because it ignores two compounding friction points: (1) the vulnerability only fires when the target uses gRPC-Go's built-in authz interceptor with a deny-rule + fallback-allow policy pattern, which is a fraction of deployments, and (2) the vast majority of gRPC services sit behind internal service meshes or API gateways, not on the public internet. The 9.1 is the theoretical ceiling; most environments sit well below it.

"Trivial auth bypass but only fires on a narrow authz pattern most gRPC-Go deployments dont use"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify gRPC endpoint

Attacker discovers a gRPC-Go service endpoint, either exposed externally through a misconfigured load balancer or reachable from a compromised internal host. Service enumeration via gRPC reflection or known proto definitions reveals available methods and services.
Conditions required:
  • Network reachability to gRPC service port (typically 443 or 50051)
  • Knowledge of service and method names (via reflection, protos, or guessing)
Where this breaks in practice:
  • Most gRPC services are internal-only behind L4/L7 load balancers or service meshes
  • gRPC reflection is often disabled in production
Detection/coverage: Network scanners detecting gRPC services (Shodan http.component:grpc); WAF/API gateway logs showing gRPC traffic from unexpected sources.
STEP 02

Craft malformed HTTP/2 :path header

Using a raw HTTP/2 client (e.g., Python h2 library), the attacker constructs a HEADERS frame with :path set to Service/Method (no leading slash). Standard gRPC clients always prepend /, so this requires a custom tool — the public PoC by JohannesLks on GitHub provides this out of the box.
Conditions required:
  • Ability to send raw HTTP/2 frames (not possible with standard gRPC client libraries)
  • Target must be running gRPC-Go < v1.79.3
Where this breaks in practice:
  • Standard gRPC stubs and clients always add the leading slash; attacker needs a custom HTTP/2 framing tool
  • Some reverse proxies (Envoy, nginx) may normalize or reject non-canonical paths before they reach the backend
Detection/coverage: HTTP/2 frame inspection at the proxy layer; log analysis for :path values missing leading slash.
STEP 03

Bypass authz deny rules

The gRPC-Go server routes the request successfully (the routing layer normalizes internally), but the authz interceptor evaluates the raw path Service/Method. Deny rules written for /Service/Method fail to match. If the policy has a fallback allow rule (common in deny-list-first RBAC patterns), the request proceeds unchecked.
Conditions required:
  • Target uses grpc/authz interceptor (NewStatic or NewFileWatcher) or custom interceptor reading raw FullMethod
  • RBAC policy uses deny-list pattern with a permissive fallback allow rule
Where this breaks in practice:
  • Many deployments use allow-list-only policies (explicit allow, default deny) which are NOT bypassed
  • Services using external authorization (OPA, Istio AuthorizationPolicy, service mesh sidecars) are unaffected
  • mTLS-only auth patterns are unaffected
Detection/coverage: Audit logs showing method calls that should have been denied; authz decision logs if instrumented.
STEP 04

Access protected methods

With authorization bypassed, the attacker invokes any gRPC method that was supposed to be denied. Impact depends on what those methods expose — could range from data exfiltration (C:H) to state mutation (I:H). In high-value deployments (infrastructure control planes, admin APIs), this can mean full service compromise.
Conditions required:
  • Successfully bypassed deny rules in step 3
Where this breaks in practice:
  • Actual impact depends on what the protected methods do — many internal services have limited blast radius
  • Additional application-layer checks (e.g., per-field authorization, tenant isolation) may still block meaningful abuse
Detection/coverage: Application-level audit trails; anomalous method invocation patterns.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNot observed. No KEV listing. No GreyNoise or Shadowserver tags as of 2026-09-10. No confirmed campaigns targeting this CVE.
Proof-of-conceptPublic. Python PoC by JohannesLks published ~June 2026. Uses h2 library for raw HTTP/2 frame crafting. Supports no-slash, double-slash, and custom :path modes.
EPSS score0.01557 (~98.4th percentile). Moderate exploitation probability reflecting the narrow trigger conditions.
KEV statusNot listed on CISA KEV as of 2026-09-10.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N — Network-reachable, no auth required, no user interaction. High confidentiality and integrity impact, no availability impact. The AC:L is accurate *if* the authz pattern is present.
Affected versionsgoogle.golang.org/grpc < v1.79.3. All prior versions using the grpc/authz interceptor package are vulnerable.
Fixed versionsgRPC-Go v1.79.3. Downstream: Traefik 2.11.42 / 3.6.12 / 3.7.0-ea.3, Datadog Agent tracking in #48151, IBM Fusion per IBM Security Bulletin, Red Hat tracking at access.redhat.com.
Scanning / exposuregRPC-Go is the dominant Go gRPC library with millions of downstream imports. However, the vulnerable *pattern* (authz interceptor + deny-list + allow fallback) is a small subset. Shodan http.component:grpc shows ~200K internet-facing gRPC endpoints globally, but language/version breakdown is unavailable.
Disclosure2026-03-17 (GHSA published), 2026-03-20 (NVD). Fix released same day as advisory.
Credited researcherNot publicly attributed in GHSA or NVD records.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to HIGH (7.5/10)

The single most decisive downgrade factor is that this bypass only triggers when the target uses gRPC-Go's built-in authz interceptor with a deny-list + fallback-allow policy pattern — a configuration subset, not the default. The 9.1 CVSS models universal applicability that does not hold across the installed base.

HIGH Vulnerability mechanism and fix confirmed via GHSA, upstream commit, and public PoC
MEDIUM Fraction of deployments using the vulnerable authz pattern (estimated minority but not precisely quantifiable)
LOW Internet-facing gRPC-Go exposure share specifically running vulnerable authz configs

Why this verdict

  • Narrow trigger condition: The bypass requires the target to use grpc/authz (or a custom interceptor reading raw FullMethod) with a deny-rule + fallback-allow policy. Deployments using allow-list-only policies, external authorization (OPA, Istio, service mesh), or mTLS-only auth are unaffected. This meaningfully reduces the reachable population below the universal scope the 9.1 CVSS assumes.
  • Internal-only exposure: The overwhelming majority of gRPC-Go services run behind service meshes, internal load balancers, or API gateways — not directly internet-facing. Exploiting from outside requires a prior foothold or a misconfigured edge, adding an implicit prerequisite the CVSS doesn't capture.
  • Trivial exploitation when conditions met: The attack is a single malformed HTTP/2 header with a public PoC. No memory corruption, no race conditions, no brute force. When the authz pattern is present, exploitation is deterministic and reliable — this prevents further downgrade.
  • Role multiplier: gRPC-Go is embedded in high-value infrastructure — Kubernetes control plane components (etcd client libraries), service mesh control planes (Istio Pilot), ingress controllers (Traefik), and monitoring agents (Datadog). However, most of these high-value consumers use mTLS or external policy engines for authorization rather than the built-in grpc/authz package. Traefik is a confirmed affected downstream in a network-edge role, keeping the floor at HIGH. If an organization's Traefik deployment relied on gRPC authz deny rules, the blast radius would be network-edge bypass → HIGH floor holds.
  • Public PoC availability: The JohannesLks PoC has been public since ~June 2026, lowering the attacker skill bar and increasing the urgency to patch even without observed exploitation.

Why not higher?

The vulnerability does not universally affect all gRPC-Go deployments — only those using the specific authz interceptor with deny-list policies. The canonical high-value consumers of gRPC-Go (etcd, Kubernetes API server, Istio) predominantly use mTLS and external policy engines, not the built-in authz package. Without evidence of active exploitation or KEV listing, and with the narrow trigger condition, CRITICAL is not warranted.

Why not lower?

The attack is unauthenticated, network-reachable, trivially exploitable with a public PoC, and results in complete authorization bypass (C:H/I:H). Traefik — a network-edge component — is a confirmed affected downstream, establishing a HIGH floor via the role-multiplier rule. The EPSS of 1.6% is non-trivial, and the Go ecosystem's broad adoption means the absolute number of vulnerable instances is significant even if the percentage is modest.

05 · Compensating Control

What to do — in priority order.

  1. Upgrade gRPC-Go to v1.79.3 immediately — The fix rejects any request with a :path missing the leading slash at the transport layer, before it reaches interceptors. This is the definitive fix. For a HIGH verdict, deploy within 30 days per noisgate mitigation SLA.
  2. Deploy reverse proxy path validation — Configure your L7 proxy (Envoy, nginx, HAProxy) to reject HTTP/2 requests where :path does not start with /. Envoy's normalize_path and merge_slashes options help. This blocks the attack before it reaches gRPC-Go.
  3. Switch to allow-list-only RBAC policies — If using grpc/authz, restructure policies to explicit allow-list (default deny) rather than deny-list + fallback allow. The bypass only works when deny rules fail to match and a fallback allow permits the request.
  4. Audit downstream Go module dependencies — Run go list -m all | grep google.golang.org/grpc across all Go services to identify which binaries embed a vulnerable gRPC-Go version. Prioritize services using grpc/authz imports.
  5. Update affected downstream packages — Patch Traefik to 2.11.42+ / 3.6.12+, Datadog Agent per vendor guidance, IBM Fusion per IBM Security Bulletin. These bundle vulnerable gRPC-Go.
What doesn't work
  • Network-level firewalling alone — if the attacker is already on the internal network (post-compromise), firewall rules between segments won't help unless they specifically inspect HTTP/2 frame content.
  • Standard gRPC client-side fixes — the vulnerability is exploited via raw HTTP/2 frames, not standard gRPC client libraries. Upgrading client-side gRPC libraries does not protect the server.
  • TLS/mTLS without authz changes — mTLS authenticates the *caller* but does not enforce method-level authorization. If the authz interceptor is still the deny-list pattern, a client with valid mTLS certs can still exploit the bypass.
06 · Verification

Crowdsourced verification payload.

Run this on each host or in CI where Go services are built. It scans go.sum files to detect vulnerable gRPC-Go versions. No special privileges needed. Example: bash check_cve_2026_33186.sh /path/to/your/go/project

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-33186 checker: detects vulnerable google.golang.org/grpc versions
# Usage: bash check_cve_2026_33186.sh <path-to-go-module-root>
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

TARGET_DIR="${1:-.}"
FIXED_VERSION="1.79.3"

if [ ! -f "$TARGET_DIR/go.sum" ] && [ ! -f "$TARGET_DIR/go.mod" ]; then
  echo "UNKNOWN: No go.sum or go.mod found in $TARGET_DIR"
  exit 2
fi

# Try go.sum first, fall back to go.mod
GRPC_VERSION=""
if [ -f "$TARGET_DIR/go.sum" ]; then
  GRPC_VERSION=$(grep -oP 'google\.golang\.org/grpc v\K[0-9]+\.[0-9]+\.[0-9]+' "$TARGET_DIR/go.sum" | sort -V | tail -1)
fi
if [ -z "$GRPC_VERSION" ] && [ -f "$TARGET_DIR/go.mod" ]; then
  GRPC_VERSION=$(grep -oP 'google\.golang\.org/grpc v\K[0-9]+\.[0-9]+\.[0-9]+' "$TARGET_DIR/go.mod" | head -1)
fi

if [ -z "$GRPC_VERSION" ]; then
  echo "UNKNOWN: google.golang.org/grpc not found in module files"
  exit 2
fi

echo "Detected gRPC-Go version: v$GRPC_VERSION"
echo "Fixed version: v$FIXED_VERSION"

# Compare versions using sort -V
LOWEST=$(printf '%s\n%s' "$GRPC_VERSION" "$FIXED_VERSION" | sort -V | head -1)

if [ "$GRPC_VERSION" = "$FIXED_VERSION" ] || [ "$LOWEST" = "$FIXED_VERSION" ]; then
  echo "PATCHED: gRPC-Go v$GRPC_VERSION >= v$FIXED_VERSION"
  exit 0
else
  echo "VULNERABLE: gRPC-Go v$GRPC_VERSION < v$FIXED_VERSION (CVE-2026-33186)"
  # Additional check: see if grpc/authz is imported
  if grep -rq 'google.golang.org/grpc/authz' "$TARGET_DIR/" 2>/dev/null; then
    echo "WARNING: This project imports grpc/authz — HIGH exploitation risk"
  else
    echo "NOTE: grpc/authz import not detected — lower exploitation risk (but custom interceptors may still be affected)"
  fi
  exit 1
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: Run the verification script across all Go codebases to identify services pinned to gRPC-Go < v1.79.3, then triage by which ones import grpc/authz or use custom path-based interceptors — those are your highest-risk targets. Per the noisgate mitigation SLA for HIGH (≤ 30 days), deploy compensating controls (L7 proxy path validation, switch to allow-list policies) on exposed services immediately while scheduling dependency upgrades. Per the noisgate remediation SLA for HIGH (≤ 180 days), bump google.golang.org/grpc to v1.79.3+ and update downstream packages (Traefik 2.11.42+/3.6.12+, Datadog Agent, IBM Fusion) across all environments. If any gRPC service using deny-list authz is internet-facing, treat it as emergency patching — do not wait 30 days.

Sources

  1. GitHub Advisory GHSA-p77j-4mvh-x3m3
  2. NVD CVE-2026-33186 Detail
  3. JohannesLks PoC — gRPC-Go RBAC Bypass
  4. Traefik Security Advisory GHSA-46wh-3698-f2cx
  5. Datadog Agent Issue #48151
  6. IBM Fusion Security Bulletin
  7. Red Hat CVE Page
  8. Go Vulnerability Database GO-2026-4762
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.