Back to Blog
high SEVERITY6 min read

Authorization Bypass in gRPC-Go HTTP/2 Path Validation (CVE-2026-33186)

A critical authorization bypass vulnerability (CVE-2026-33186) in `google.golang.org/grpc` v1.79.1 allowed attackers to circumvent gRPC authorization policies through malformed HTTP/2 path values. The fix upgrades the dependency in `src/go/go.mod` from v1.79.1 to v1.79.3, closing a path validation gap in the `grpc-go/authz` middleware that could have exposed protected RPC endpoints to unauthorized callers.

O
By Orbis AppSec
Published May 30, 2026Reviewed June 3, 2026

Answer Summary

CVE-2026-33186 is a critical authorization bypass vulnerability (related to CWE-863: Incorrect Authorization) in the `google.golang.org/grpc` Go library (versions up to v1.79.1) where the `grpc-go/authz` middleware failed to properly validate malformed HTTP/2 `:path` pseudo-header values, allowing attackers to call protected RPC methods without authorization. The fix is a dependency upgrade from `google.golang.org/grpc v1.79.1` to `v1.79.3` in `src/go/go.mod`, which patches the path normalization logic in the authorization middleware so that crafted path values can no longer circumvent policy evaluation.

Vulnerability at a Glance

cweCWE-863 (Incorrect Authorization)
fixUpgrade google.golang.org/grpc from v1.79.1 to v1.79.3 in src/go/go.mod
riskUnauthorized callers can invoke protected gRPC RPC endpoints, bypassing all authorization policies
languageGo
root causeThe grpc-go/authz middleware did not normalize or reject malformed HTTP/2 :path pseudo-header values before evaluating authorization rules
vulnerabilityAuthorization Bypass via Malformed HTTP/2 Path Values

Authorization Bypass in gRPC-Go HTTP/2 Path Validation (CVE-2026-33186)

Introduction

The src/go/go.mod file in this Moby-based containerized service pulls in google.golang.org/grpc as an indirect dependency — one of the most widely used RPC frameworks in the Go ecosystem. Because it sits behind an // indirect comment, it's easy to overlook during routine dependency audits. That oversight nearly cost this project dearly: grpc-go v1.79.1 ships with a critical authorization bypass (CVE-2026-33186) rooted in how the authz middleware validates HTTP/2 :path pseudo-headers.

This post breaks down exactly what went wrong, why HTTP/2 path handling is a surprisingly tricky security surface, and how a two-line change to go.mod and a checksum update in go.sum sealed the gap.


The Vulnerability Explained

gRPC Authorization and the HTTP/2 :path Header

gRPC-Go's google.golang.org/grpc/authz package provides policy-based authorization for RPC methods. Under the hood, every gRPC call maps to an HTTP/2 request where the method path — e.g., /mypackage.MyService/MyMethod — is carried in the :path pseudo-header.

Authorization rules are typically written against these path strings:

// Example authz policy (simplified)
{
  "rules": [{
    "name": "block-admin",
    "source": {"principals": ["*"]},
    "request": {"paths": ["/admin.AdminService/*"]}
  }]
}

The vulnerability lies in how authz normalizes the :path value before matching it against policy rules. In v1.79.1, certain malformed or non-canonical path representations — such as paths with unexpected percent-encoding, double slashes, or other HTTP/2-legal-but-semantically-ambiguous constructs — were not consistently normalized. This created a mismatch: the policy engine evaluated one string while the actual RPC dispatcher resolved another.

The Exploitable Pattern

Consider a service that protects /admin.AdminService/DeleteUser behind an authorization rule. An attacker who can send raw HTTP/2 frames could craft a :path value like:

/admin.AdminService/%44eleteUser

or

//admin.AdminService/DeleteUser

The authz middleware, operating on the raw or inconsistently normalized value, might not match the deny rule — passing the request through to the RPC handler as if it were authorized. The dispatcher, which performs its own normalization, resolves the path correctly and executes the privileged method.

This is a classic TOCTOU-style normalization mismatch: the security check and the execution engine disagree on what the path actually means.

Why This Matters for a Containerized Moby Service

In a containerized environment, gRPC endpoints are often exposed on internal networks with the assumption that the authorization middleware is the primary access control layer. If that layer can be bypassed by a network-adjacent attacker — or even a compromised container on the same overlay network — the blast radius is significant. Any RPC method behind an authz policy could be reachable without credentials or role membership.

The Trivy scanner flagged this in src/go/go.mod with severity CRITICAL and assessment "Likely exploitable", indicating the vulnerable code path is reachable in the production build.


The Fix

What Changed

The fix is surgical: a single version bump in src/go/go.mod and the corresponding checksum entries in src/go/go.sum.

src/go/go.mod — before:

google.golang.org/grpc v1.79.1 // indirect

src/go/go.mod — after:

google.golang.org/grpc v1.79.3 // indirect

Additionally, a previously missing transitive dependency was pinned explicitly:

// Added to the indirect require block:
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect

src/go/go.sum — new checksums added:

google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:...
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:...

Why Each Change Was Necessary

Change Purpose
grpc v1.79.1v1.79.3 Pulls in the patched authz path normalization logic
Added genproto/googleapis/rpc explicit pin v1.79.3 tightened its RPC type dependencies; pinning ensures reproducible builds and prevents the module graph from silently resolving an older, potentially vulnerable version
Updated go.sum hashes Go's module verification requires cryptographic checksums for every resolved module version; without these, go build would refuse to proceed

The grpc-go v1.79.3 patch introduces canonical normalization of the HTTP/2 :path pseudo-header inside the authz interceptor before policy evaluation, ensuring the string the security check operates on is identical to the string the dispatcher will use. The fix eliminates the normalization mismatch at its source.


Prevention & Best Practices

1. Treat Indirect Dependencies as First-Class Security Concerns

The vulnerable line in go.mod was marked // indirect — meaning no first-party code directly imports grpc. It's a transitive dependency pulled in by another library. Indirect dependencies are just as exploitable as direct ones and must be included in vulnerability scanning.

Action: Configure Trivy, govulncheck, or Dependabot to scan all dependencies, not just direct imports.

# Run govulncheck on your module
govulncheck ./...

# Or use trivy on your go.mod directly
trivy fs --scanners vuln src/go/go.mod

2. Pin and Audit gRPC Authorization Middleware Separately

If you use google.golang.org/grpc/authz, treat it as a security-critical component. Add it as a direct dependency in go.mod even if it's technically indirect, so version changes are explicit and visible in code review:

require (
    google.golang.org/grpc v1.79.3
    // Explicitly track authz-bearing grpc version
)

3. Validate HTTP/2 Path Inputs at the Application Layer Too

Even with a patched framework, defense-in-depth recommends validating RPC method paths at the application layer:

// In your gRPC server interceptor
func pathValidationInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
    method := info.FullMethod
    if !isCanonicalGRPCPath(method) {
        return nil, status.Errorf(codes.InvalidArgument, "malformed method path: %s", method)
    }
    return handler(ctx, req)
}

func isCanonicalGRPCPath(path string) bool {
    // Must start with /, no double slashes, no percent-encoding
    return strings.HasPrefix(path, "/") &&
        !strings.Contains(path, "//") &&
        !strings.ContainsRune(path, '%')
}

4. Use go mod tidy + go mod verify in CI

# Ensure the module graph is consistent
go mod tidy

# Verify all downloaded modules match go.sum checksums
go mod verify

Failing CI on go mod verify discrepancies catches tampered or unexpected dependency versions before they reach production.

5. Relevant Standards and References

  • CWE-863: Incorrect Authorization
  • CWE-116: Improper Encoding or Escaping of Output (path normalization failure)
  • OWASP ASVS v4.0, Section 4.1: Access Control Design Requirements — specifically, that access control checks must use the same representation of a resource as the enforcement point
  • gRPC Security Best Practices: https://grpc.io/docs/guides/security/

Key Takeaways

  • // indirect in go.mod does not mean "low risk" — CVE-2026-33186 lived in an indirect dependency and was rated CRITICAL. Scan everything.
  • HTTP/2 path normalization is a security boundary — the authz middleware in grpc-go v1.79.1 evaluated paths before canonicalization, creating a gap between the security check and the dispatcher. v1.79.3 closes this by normalizing first.
  • The genproto/googleapis/rpc pin was not cosmetic — explicitly adding it to go.mod ensures the build graph is deterministic and that no older RPC type package can be silently resolved, which could reintroduce instability in the patched code paths.
  • Authorization bypass vulnerabilities in RPC frameworks are high-value targets in containerized environments where gRPC endpoints are assumed to be protected by middleware alone.
  • A two-line diff can fix a critical vulnerability — but only if your scanner is configured to catch it. The Trivy rule CVE-2026-33186 found this; without automated scanning, it would have shipped.

Conclusion

CVE-2026-33186 is a reminder that the security of your gRPC service is only as strong as the path normalization logic in your authorization middleware. In this case, google.golang.org/grpc v1.79.1 — quietly sitting in src/go/go.mod as an indirect dependency — contained a flaw that could allow an attacker to bypass carefully crafted authorization policies by sending a semantically equivalent but syntactically non-canonical HTTP/2 path.

The fix is minimal in code footprint but significant in impact: upgrading to v1.79.3 ensures the authz interceptor and the RPC dispatcher always agree on what path is being requested. Combined with the explicit genproto/googleapis/rpc pin for build reproducibility, this change closes the vulnerability cleanly.

If your Go services use gRPC — directly or transitively — audit your go.mod today. Run govulncheck ./... and make sure your indirect dependencies are held to the same security standard as your first-party code.


This vulnerability was identified and remediated by Orbis AppSec automated security tooling.

Frequently Asked Questions

What is an authorization bypass vulnerability in gRPC-Go?

It is a flaw where the gRPC authorization middleware fails to correctly enforce access policies, allowing an attacker to call RPC methods they should not be permitted to access — in this case by sending a crafted HTTP/2 :path header that the middleware misinterprets.

How do you prevent authorization bypass in Go gRPC services?

Keep your google.golang.org/grpc dependency up to date, use the grpc-go/authz middleware with strict policy definitions, validate and normalize all incoming HTTP/2 pseudo-headers, and apply defense-in-depth with network-level controls alongside application-level authorization.

What CWE is authorization bypass?

Authorization bypass vulnerabilities are typically classified under CWE-863 (Incorrect Authorization) or the broader CWE-284 (Improper Access Control), depending on whether the flaw is in policy evaluation logic or a missing control entirely.

Is using TLS enough to prevent this authorization bypass?

No. TLS encrypts the transport but does not enforce which authenticated callers can invoke which RPC methods. The bypass exploited the authorization policy evaluation logic itself, so transport security alone would not have stopped it.

Can static analysis detect this authorization bypass?

Dependency-scanning tools (such as govulncheck, Dependabot, or Orbis AppSec) can detect known-vulnerable versions of google.golang.org/grpc and flag CVE-2026-33186 automatically. Deep static analysis of the middleware path-parsing logic can also surface the missing normalization step.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #22587

Related Articles

critical

How path traversal happens in Python os.path and how to fix it

A critical path traversal vulnerability in the TRL backend allowed attackers to read arbitrary system files like `/etc/passwd` and `/proc/self/environ` through the gRPC fine-tuning API. The `_do_training` method passed user-controlled `dataset_source` directly to `os.path.exists()` and `load_dataset()` without validation. The fix implements strict directory containment checks using `os.path.realpath()` to ensure all file operations stay within allowed directories.

high

Shell Injection via Unsafe String Concatenation in gRPC Command Generation

A high-severity shell injection vulnerability was discovered in `src/RtlJaguarDevice.cpp`, where user-controlled values from API responses were directly interpolated into gRPCurl command strings without proper shell escaping. An attacker who controls API response data could inject shell metacharacters, causing arbitrary command execution when a user pastes and runs the generated command. The fix applies proper shell escaping to all user-controlled values before they are included in command strin

high

Shell Injection via Unsafe String Concatenation in CXLMemSim gRPCurl Commands

A high-severity shell injection vulnerability was discovered and patched in a distributed server's gRPCurl command generation logic, where user-controlled values from API responses were directly interpolated into shell command strings without proper escaping. An attacker who can influence API response data — such as headers, endpoints, or payloads — could inject shell metacharacters that execute arbitrary commands when a user pastes and runs the generated command. This fix eliminates the risk by

high

Shell Injection via gRPCurl Command Generation: A Hidden Android Threat

A high-severity shell injection vulnerability was discovered and fixed in the HeadUnit Revived Android project, where user-controlled API response values were unsafely interpolated into gRPCurl command strings. An attacker could craft malicious headers, endpoints, or data payloads containing shell metacharacters that, when the generated command is pasted and executed, would run arbitrary commands on the victim's machine. The fix introduces proper shell escaping and broadcast intent protection to

critical

Stack Buffer Overflow in C++ gRPC Server: How sprintf() Enables Code Execution

A critical stack buffer overflow vulnerability was discovered in the ik-llama-cpp gRPC inference server, where three unguarded sprintf() calls wrote formatted statistics into fixed-size stack buffers without any length restrictions. If exploited, an attacker could overwrite return addresses and saved frame pointers, potentially achieving arbitrary code execution on the server. The fix replaces the unsafe sprintf() calls with length-aware alternatives, closing the door on this dangerous memory co

high

How missing Dependabot cooldown happens in GitHub Actions and how to fix it

A high-severity configuration vulnerability was discovered in a `.github/dependabot.yml` file that lacked a cooldown period for package updates. Without this safeguard, Dependabot could immediately propose updates to newly published package versions—including potentially malicious or unstable releases. The fix adds a simple `cooldown` block with a 7-day waiting period before any new package version is suggested.