CVE-2026-71397 (GCVE-0-2026-71397)
Vulnerability from cvelistv5 – Published: 2026-11-06 21:02 – Updated: 2026-11-06 21:02
VLAI
EPSS
VEX
Title
Unbounded request body accumulation on streaming RPCs causes memory exhaustion in grpc_server
Summary
Allocation of Resources Without Limits or Throttling vulnerability in elixir-grpc grpc_server allows unauthenticated attackers to exhaust memory and crash the node via an oversized client-streaming or bidirectional-streaming request body.
The streaming read clause of 'Elixir.GRPC.Server.Adapters.Cowboy.Handler':info/3 (grpc_server/lib/grpc/server/adapters/cowboy/handler.ex) never checks the configured max_body_size. Only the unary read path enforces that cap. 'Elixir.GRPC.Server.Adapters.Cowboy':reading_stream/1 (grpc_server/lib/grpc/server/adapters/cowboy.ex) appends every received chunk to its buffer until a complete length-prefixed message arrives. A client can declare a very large message and send it across many small HTTP/2 DATA frames, and the server buffers all of it.
This issue affects grpc_server: from 1.0.0 before 1.0.6.
Severity
CWE
- CWE-770 - Allocation of Resources Without Limits or Throttling
Assigner
EEF
CNA
References
5 references
| URL | Tags |
|---|---|
| https://github.com/elixir-grpc/grpc/security/advi… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-71397.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-71397 | related |
| https://github.com/elixir-grpc/grpc/commit/49e18c… | related |
| https://github.com/elixir-grpc/grpc/commit/0b663c… | patch |
Impacted products
2 products
| Vendor | Product | Version | |
|---|---|---|---|
| elixir-grpc | grpc_server |
Affected:
1.0.0 , < 1.0.6
(semver)
cpe:2.3:a:elixir-grpc:grpc_server:*:*:*:*:*:*:*:* |
|
| elixir-grpc | grpc_server |
Affected:
49e18c3ec6bb9afe2f712caad3dbab5c56a68a00 , < 0b663ca53dbf0f36f7f67ff1d0026f4482a18915
(git)
cpe:2.3:a:elixir-grpc:grpc_server:*:*:*:*:*:*:*:* |
{
"containers": {
"cna": {
"affected": [
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:elixir-grpc:grpc_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027",
"\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027"
],
"packageName": "grpc_server",
"packageURL": "pkg:hex/grpc_server",
"product": "grpc_server",
"programFiles": [
"lib/grpc/server/adapters/cowboy/handler.ex",
"lib/grpc/server/adapters/cowboy.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3"
},
{
"name": "\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1"
}
],
"repo": "https://github.com/elixir-grpc/grpc",
"vendor": "elixir-grpc",
"versions": [
{
"lessThan": "1.0.6",
"status": "affected",
"version": "1.0.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:elixir-grpc:grpc_server:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027",
"\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027"
],
"packageName": "elixir-grpc/grpc",
"packageURL": "pkg:github/elixir-grpc/grpc",
"product": "grpc_server",
"programFiles": [
"grpc_server/lib/grpc/server/adapters/cowboy/handler.ex",
"grpc_server/lib/grpc/server/adapters/cowboy.ex"
],
"programRoutines": [
{
"name": "\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3"
},
{
"name": "\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1"
}
],
"repo": "https://github.com/elixir-grpc/grpc",
"vendor": "elixir-grpc",
"versions": [
{
"lessThan": "0b663ca53dbf0f36f7f67ff1d0026f4482a18915",
"status": "affected",
"version": "49e18c3ec6bb9afe2f712caad3dbab5c56a68a00",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe server must expose at least one client-streaming or bidirectional-streaming RPC method.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The server must expose at least one client-streaming or bidirectional-streaming RPC method."
}
],
"value": "The server must expose at least one client-streaming or bidirectional-streaming RPC method."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:elixir-grpc:grpc_server:*:*:*:*:*:*:*:*",
"versionEndExcluding": "1.0.6",
"versionStartIncluding": "1.0.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Arpit Jain"
},
{
"lang": "en",
"type": "reporter",
"value": "Arpit Jain"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Arpit Jain"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Paulo Valente"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAllocation of Resources Without Limits or Throttling vulnerability in elixir-grpc grpc_server allows unauthenticated attackers to exhaust memory and crash the node via an oversized client-streaming or bidirectional-streaming request body.\u003c/p\u003e\n\u003cp\u003eThe streaming read clause of \u003ccode\u003e\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3\u003c/code\u003e (\u003ccode\u003egrpc_server/lib/grpc/server/adapters/cowboy/handler.ex\u003c/code\u003e) never checks the configured \u003ccode\u003emax_body_size\u003c/code\u003e. Only the unary read path enforces that cap. \u003ccode\u003e\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1\u003c/code\u003e (\u003ccode\u003egrpc_server/lib/grpc/server/adapters/cowboy.ex\u003c/code\u003e) appends every received chunk to its buffer until a complete length-prefixed message arrives. A client can declare a very large message and send it across many small HTTP/2 DATA frames, and the server buffers all of it.\u003c/p\u003e\n\u003cp\u003eThis issue affects grpc_server: from 1.0.0 before 1.0.6.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Allocation of Resources Without Limits or Throttling vulnerability in elixir-grpc grpc_server allows unauthenticated attackers to exhaust memory and crash the node via an oversized client-streaming or bidirectional-streaming request body.\n\nThe streaming read clause of `\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3` (`grpc_server/lib/grpc/server/adapters/cowboy/handler.ex`) never checks the configured `max_body_size`. Only the unary read path enforces that cap. `\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1` (`grpc_server/lib/grpc/server/adapters/cowboy.ex`) appends every received chunk to its buffer until a complete length-prefixed message arrives. A client can declare a very large message and send it across many small HTTP/2 DATA frames, and the server buffers all of it.\n\nThis issue affects grpc_server: from 1.0.0 before 1.0.6."
}
],
"value": "Allocation of Resources Without Limits or Throttling vulnerability in elixir-grpc grpc_server allows unauthenticated attackers to exhaust memory and crash the node via an oversized client-streaming or bidirectional-streaming request body.\n\nThe streaming read clause of \u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3 (grpc_server/lib/grpc/server/adapters/cowboy/handler.ex) never checks the configured max_body_size. Only the unary read path enforces that cap. \u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1 (grpc_server/lib/grpc/server/adapters/cowboy.ex) appends every received chunk to its buffer until a complete length-prefixed message arrives. A client can declare a very large message and send it across many small HTTP/2 DATA frames, and the server buffers all of it.\n\nThis issue affects grpc_server: from 1.0.0 before 1.0.6."
}
],
"impacts": [
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn unauthenticated client can crash a \u003ccode\u003egrpc_server\u003c/code\u003e node through one streaming RPC connection. This takes down every service on that node.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An unauthenticated client can crash a `grpc_server` node through one streaming RPC connection. This takes down every service on that node."
}
],
"value": "An unauthenticated client can crash a grpc_server node through one streaming RPC connection. This takes down every service on that node."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-770",
"description": "CWE-770 Allocation of Resources Without Limits or Throttling",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-11-06T21:02:03.676Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "Unbounded request body accumulation on streaming RPCs causes memory exhaustion in grpc_server",
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/elixir-grpc/grpc/security/advisories/GHSA-vx6q-cr5q-945g"
},
{
"name": "EEF CNA record for CVE-2026-71397",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-71397.html"
},
{
"name": "OSV record EEF-CVE-2026-71397",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-71397"
},
{
"name": "Introducing commit 49e18c3 in elixir-grpc/grpc",
"tags": [
"related"
],
"url": "https://github.com/elixir-grpc/grpc/commit/49e18c3ec6bb9afe2f712caad3dbab5c56a68a00"
},
{
"name": "Fix commit 0b663ca in elixir-grpc/grpc",
"tags": [
"patch"
],
"url": "https://github.com/elixir-grpc/grpc/commit/0b663ca53dbf0f36f7f67ff1d0026f4482a18915"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Unbounded request body accumulation on streaming RPCs causes memory exhaustion in grpc_server",
"x_proofOfConcept": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003col\u003e\n\u003cli\u003eStart a \u003ccode\u003egrpc_server\u003c/code\u003e endpoint that exposes a client-streaming or bidirectional-streaming RPC method.\u003c/li\u003e\n\u003cli\u003eOpen an HTTP/2 connection and send a request to that method.\u003c/li\u003e\n\u003cli\u003eSend the request body across many small HTTP/2 DATA frames without \u003ccode\u003eEND_STREAM\u003c/code\u003e, well past the configured \u003ccode\u003emax_body_size\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eObserve that the server buffers all of it and server memory grows. The equivalent unary call is rejected with \u003ccode\u003eRESOURCE_EXHAUSTED\u003c/code\u003e.\u003c/li\u003e\n\u003c/ol\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "1. Start a `grpc_server` endpoint that exposes a client-streaming or bidirectional-streaming RPC method.\n2. Open an HTTP/2 connection and send a request to that method.\n3. Send the request body across many small HTTP/2 DATA frames without `END_STREAM`, well past the configured `max_body_size`.\n4. Observe that the server buffers all of it and server memory grows. The equivalent unary call is rejected with `RESOURCE_EXHAUSTED`."
}
],
"value": "* Start a grpc_server endpoint that exposes a client-streaming or bidirectional-streaming RPC method.\n* Open an HTTP/2 connection and send a request to that method.\n* Send the request body across many small HTTP/2 DATA frames without END_STREAM, well past the configured max_body_size.\n* Observe that the server buffers all of it and server memory grows. The equivalent unary call is rejected with RESOURCE_EXHAUSTED."
}
],
"x_technicalAnalysis": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003e\u003cstrong\u003e1. The cap applies to unary reads only\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eThe commit that added \u003ccode\u003emax_body_size\u003c/code\u003e checks it in \u003ccode\u003eread_full_body/4\u003c/code\u003e, which serves unary requests through the \u003ccode\u003e{:read_full_body, ref, pid}\u003c/code\u003e clause of \u003ccode\u003e\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3\u003c/code\u003e. The \u003ccode\u003e{:read_body, ref, pid}\u003c/code\u003e clause, which serves streaming requests, returns each chunk to the caller with no size check.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. Unbounded buffering\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003e\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1\u003c/code\u003e reads chunks through that clause and appends each one to a binary buffer. It emits a message only when \u003ccode\u003eGRPC.Message.get_message/1\u003c/code\u003e finds a complete length-prefixed gRPC message in the buffer. Until then, the buffer grows with every chunk.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Memory exhaustion\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eA client that declares a large message length and keeps sending DATA frames without \u003ccode\u003eEND_STREAM\u003c/code\u003e makes the buffer grow without limit. The BEAM eventually runs out of memory and the node crashes.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "**1. The cap applies to unary reads only**\n\nThe commit that added `max_body_size` checks it in `read_full_body/4`, which serves unary requests through the `{:read_full_body, ref, pid}` clause of `\u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3`. The `{:read_body, ref, pid}` clause, which serves streaming requests, returns each chunk to the caller with no size check.\n\n**2. Unbounded buffering**\n\n`\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1` reads chunks through that clause and appends each one to a binary buffer. It emits a message only when `GRPC.Message.get_message/1` finds a complete length-prefixed gRPC message in the buffer. Until then, the buffer grows with every chunk.\n\n**3. Memory exhaustion**\n\nA client that declares a large message length and keeps sending DATA frames without `END_STREAM` makes the buffer grow without limit. The BEAM eventually runs out of memory and the node crashes."
}
],
"value": "1. The cap applies to unary reads only\n\nThe commit that added max_body_size checks it in read_full_body/4, which serves unary requests through the {:read_full_body, ref, pid} clause of \u0027Elixir.GRPC.Server.Adapters.Cowboy.Handler\u0027:info/3. The {:read_body, ref, pid} clause, which serves streaming requests, returns each chunk to the caller with no size check.\n\n2. Unbounded buffering\n\n\u0027Elixir.GRPC.Server.Adapters.Cowboy\u0027:reading_stream/1 reads chunks through that clause and appends each one to a binary buffer. It emits a message only when GRPC.Message.get_message/1 finds a complete length-prefixed gRPC message in the buffer. Until then, the buffer grows with every chunk.\n\n3. Memory exhaustion\n\nA client that declares a large message length and keeps sending DATA frames without END_STREAM makes the buffer grow without limit. The BEAM eventually runs out of memory and the node crashes."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-71397",
"datePublished": "2026-11-06T21:02:03.676Z",
"dateReserved": "2026-08-19T10:30:01.929Z",
"dateUpdated": "2026-11-06T21:02:03.676Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
Loading…
Loading…
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
Loading timeline…
Loading…
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Loading…
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.