See how grpc compares to other vendors in security performance
Google gRPC before 2017-04-05 has an out-of-bounds write caused by a heap-based buffer overflow related to core/lib/iomgr/error.c.
Google gRPC before 2017-03-29 has an out-of-bounds write caused by a heap-based use-after-free related to the grpccalldestroy function in core/lib/surface/call.c.
Google gRPC before 2017-02-22 has an out-of-bounds write related to the gprfree function in core/lib/support/alloc.c.
Google gRPC before 2017-02-22 has an out-of-bounds write caused by a heap-based buffer overflow related to the parseunix function in core/ext/clientchannel/parseaddress.c.
The package grpc before 1.24.4; the package @grpc/grpc-js before 1.1.8 are vulnerable to Prototype Pollution via loadPackageDefinition.
Impact What kind of vulnerability is it? Who is impacted?
It is an Authorization Bypass resulting from Improper Input Validation of the HTTP/2 :path pseudo-header.
The gRPC-Go server was too lenient in its routing logic, accepting requests where the :path omitted the mandatory leading slash (e.g., Service/Method instead of /Service/Method). While the server successfully routed these requests to the correct handler, authorization interceptors (including the official grpc/authz package) evaluated the raw, non-canonical path string. Consequently, "deny" rules defined using canonical paths (starting with /) failed to match the incoming request, allowing it to bypass the policy if a fallback "allow" rule was present.
Who is impacted? This affects gRPC-Go servers that meet both of the following criteria: 1. They use path-based authorization interceptors, such as the official RBAC implementation in google.golang.org/grpc/authz or custom interceptors relying on info.FullMethod or grpc.Method(ctx). 2. Their security policy contains specific "deny" rules for canonical paths but allows other requests by default (a fallback "allow" rule).
The vulnerability is exploitable by an attacker who can send raw HTTP/2 frames with malformed :path headers directly to the gRPC server.
Patches Has the problem been patched? What versions should users upgrade to?
Yes, the issue has been patched. The fix ensures that any request with a :path that does not start with a leading slash is immediately rejected with a codes.Unimplemented error, preventing it from reaching authorization interceptors or handlers with a non-canonical path string.
Users should upgrade to the following versions (or newer): v1.79.3 The latest master branch.
It is recommended that all users employing path-based authorization (especially grpc/authz) upgrade as soon as the patch is available in a tagged release.
Workarounds Is there a way for users to fix or remediate the vulnerability without upgrading?
While upgrading is the most secure and recommended path, users can mitigate the vulnerability using one of the following methods:
1. Use a Validating Interceptor (Recommended Mitigation) Add an "outermost" interceptor to your server that validates the path before any other authorization logic runs:
go func pathValidationInterceptor(ctx context.Context, req any, info grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { if info.FullMethod == "" || info.FullMethod[0] != '/' { return nil, status.Errorf(codes.Unimplemented, "malformed method name") } return handler(ctx, req) }
// Ensure this is the FIRST interceptor in your chain s := grpc.NewServer( grpc.ChainUnaryInterceptor(pathValidationInterceptor, authzInterceptor), )
2. Infrastructure-Level Normalization If your gRPC server is behind a reverse proxy or load balancer (such as Envoy, NGINX, or an L7 Cloud Load Balancer), ensure it is configured to enforce strict HTTP/2 compliance for pseudo-headers and reject or normalize requests where the :path header does not start with a leading slash.
3. Policy Hardening Switch to a "default deny" posture in your authorization policies (explicitly listing all allowed paths and denying everything else) to reduce the risk of bypasses via malformed inputs.
Denial of Service through Data corruption in gRPC-C++
A flaw was found in ml-metadata. The statically-linked gRPC stack in ml-metadata is outdated, making it vulnerable to known HTTP/2 denial of service (DoS) issues. An in-cluster attacker, with network access to the MLMD pod, could exploit these vulnerabilities by sending specially crafted HTTP/2 requests. This could lead to a denial of service by crashing the MLMD pod, disrupting all pipeline runs in the affected namespace.
Denial of Service in gRPC Core
HTTP/2 Rapid reset attack The HTTP/2 protocol allows clients to indicate to the server that a previous stream should be canceled by sending a RSTSTREAM frame. The protocol does not require the client and server to coordinate the cancellation in any way, the client may do it unilaterally. The client may also assume that the cancellation will take effect immediately when the server receives the RSTSTREAM frame, before any other data from that TCP connection is processed.
Abuse of this feature is called a Rapid Reset attack because it relies on the ability for an endpoint to send a RSTSTREAM frame immediately after sending a request frame, which makes the other endpoint start working and then rapidly resets the request. The request is canceled, but leaves the HTTP/2 connection open.
The HTTP/2 Rapid Reset attack built on this capability is simple: The client opens a large number of streams at once as in the standard HTTP/2 attack, but rather than waiting for a response to each request stream from the server or proxy, the client cancels each request immediately.
The ability to reset streams immediately allows each connection to have an indefinite number of requests in flight. By explicitly canceling the requests, the attacker never exceeds the limit on the number of concurrent open streams. The number of in-flight requests is no longer dependent on the round-trip time (RTT), but only on the available network bandwidth.
In a typical HTTP/2 server implementation, the server will still have to do significant amounts of work for canceled requests, such as allocating new stream data structures, parsing the query and doing header decompression, and mapping the URL to a resource. For reverse proxy implementations, the request may be proxied to the backend server before the RSTSTREAM frame is processed. The client on the other hand paid almost no costs for sending the requests. This creates an exploitable cost asymmetry between the server and the client.
Multiple software artifacts implementing HTTP/2 are affected. This advisory was originally ingested from the swift-nio-http2 repo advisory and their original conent follows.
swift-nio-http2 specific advisory swift-nio-http2 is vulnerable to a denial-of-service vulnerability in which a malicious client can create and then reset a large number of HTTP/2 streams in a short period of time. This causes swift-nio-http2 to commit to a large amount of expensive work which it then throws away, including creating entirely new Channels to serve the traffic. This can easily overwhelm an EventLoop and prevent it from making forward progress.
swift-nio-http2 1.28 contains a remediation for this issue that applies reset counter using a sliding window. This constrains the number of stream resets that may occur in a given window of time. Clients violating this limit will have their connections torn down. This allows clients to continue to cancel streams for legitimate reasons, while constraining malicious actors.
Denial-of-Service in gRPC
gRPC could allow a remote attacker to obtain sensitive information, caused by a flaw when gRPC HTTP2 stack raised a header size exceeded error. By sending a specially crafted request, an attacker could exploit this vulnerability to obtain sensitive information, and use this information to launch further attacks against the affected system.
gRPC is vulnerable to a denial of service. By sending a specially crafted header, an attacker could exploit this vulnerability to cause a denial of service.
HPACK table poisoning in gRPC C++, Python & Ruby
Denial-of-Service in gRPC
There exists an vulnerability causing an abort() to be called in gRPC. The following headers cause gRPC's C++ implementation to abort() when called via http2: te: x (x != trailers) :scheme: x (x != http, https) grpclbclientstats: x (x == anything) On top of sending one of those headers, a later header must be sent that gets the total header size past 8KB. We recommend upgrading past git commit 2485fa94bd8a723e5c977d55a3ce10b301b437f8 or v1.53 and above.
When gRPC HTTP2 stack raised a header size exceeded error, it skipped parsing the rest of the HPACK frame. This caused any HPACK table mutations to also be skipped, resulting in a desynchronization of HPACK tables between sender and receiver. If leveraged, say, between a proxy and a backend, this could lead to requests from the proxy being interpreted as containing headers from different proxy clients - leading to an information leak that can be used for privilege escalation or data exfiltration. We recommend upgrading beyond the commit contained in https://github.com/grpc/grpc/pull/32309 https://github.com/grpc/grpc/pull/32309
There exists a denial of service through Data corruption in gRPC-C++ - gRPC-C++ servers with transmit zero copy enabled through the channel arg GRPCARGTCPTXZEROCOPYENABLED can experience data corruption issues. The data sent by the application may be corrupted before transmission over the network thus leading the receiver to receive an incorrect set of bytes causing RPC requests to fail. We recommend upgrading past commit e9046b2bbebc0cb7f5dc42008f807f6c7e98e791
Finding The statically-linked gRPC stack is pinned to v1.46.3 (2022) in the Bazel WORKSPACE file, predating multiple HTTP/2 DoS CVEs that are directly reachable on the network listener:
WORKSPACE:116-117 comgithubgrpcgrpc → gRPC 1.46.3 WORKSPACE:129-130 comgoogleprotobuf → protobuf 3.21.12 WORKSPACE:173-176 zlib → 1.3 The MLMD server is a network-facing gRPC listener (FIND-001: no auth), so gRPC-layer DoS CVEs are directly reachable from any pod that can open a TCP connection to :8080.
The Bazel WORKSPACE pins are content-addressed (sha256), so the issue is staleness, not mutability. Renovate is present (.github/renovate.json) but evidently not covering Bazel httparchive entries.
File: WORKSPACE:116-117,129-130,173-176 Repository: red-hat-data-services/ml-metadata Framework: ASVS V14.2.1; OWASP K8s K07 Vulnerable Components; OpenSSF Scorecard Vulnerabilities CWE: CWE-1395 / CWE-1104 CVSS v3.1: 7.5 (High) AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (inherits gRPC HTTP/2 DoS vectors)
RHOAI Mitigation The DSPO-deployed NetworkPolicy restricts who can reach MLMD port 8080 to only KFP v2 driver pods and DSP components. This limits the attack surface but does not eliminate it — a compromise of a KFP driver pod or DSP component could exploit these CVEs to crash the MLMD pod and disrupt all pipeline runs in the namespace.
Impact An in-cluster attacker who can reach the MLMD pod (within the NetworkPolicy allowlist) can crash or resource-exhaust the MLMD pod via known gRPC/HTTP2 frame-handling bugs, disrupting all pipeline runs in the namespace.
Context ml-metadata is planned for removal from the product (several months out). The stale dependency risk remains active until removal is complete.
Remediation Bump WORKSPACE pins: gRPC >= 1.62, protobuf >= 25.x, zlib >= 1.3.1. Extend Renovate configuration to cover Bazel httparchive entries.
On 10/10/23 11:40, Alan Coopersmith wrote: Information I've found so far on open source implementations (most via the current listings in the CVE) include: Some more updates since last week: - Apache httpd: https://chaos.social/@icing/111210915918780532 The discussion in https://github.com/apache/httpd-site/pull/10 makes the situation a little murkier.
- contour: https://github.com/projectcontour/contour/pull/5850
- grpc-go: https://github.com/grpc/grpc-go/pull/6703 - haproxy: https://github.com/haproxy/haproxy/issues/2312 https://www.haproxy.com/blog/haproxy-is-not-affected-by-the-http-2-rapid-reset-attack-cve-2023-44487 - http2 [Haskell]: https://github.com/kazu-yamamoto/http2/issues/93
- IETF: https://lists.w3.org/Archives/Public/ietf-http-wg/2023OctDec/0025.html
- kubernetes: https://github.com/kubernetes/kubernetes/pull/121120
- linkerd: https://linkerd.io/2023/10/12/linkerd-cve-2023-44487/ - netty: https://github.com/netty/netty/commit/58f75f665aa81a8cbcf6ffa74820042a285c5e61 https://github.com/advisories/GHSA-xpw8-rcwv-8f8p https://netty.io/news/2023/10/10/4-1-100-Final.html
- varnish https://github.com/varnishcache/varnish-cache/issues/3996
Also,https://mstdn.social/@jschauma/111252863550361935 points out that the Rust h2 crate seems to have announced a very similar issue under a different CVE id back in April:
https://rustsec.org/advisories/RUSTSEC-2023-0034.html https://github.com/advisories/GHSA-f8vr-r385-rh5r
and a followup post notes further similarities to Netflix's CVE-2019-9514 “Reset Flood” from https://github.com/Netflix/security-bulletins/blob/master/advisories/third-party/2019-002.md except in that case the RSTSTREAM seem to have been sent from the server, not the client side.
-- -Alan Coopersmith- alan.coopersmith () oracle com Oracle Solaris Engineering - https://blogs.oracle.com/solaris