Security
Oct 23, 2026

CVE-2026-92707: MessagePack-CSharp Memory Exhaustion via SignalR

CVE-2026-92707 lets nested array headers turn a 31.5 KiB MessagePack payload into roughly 115 MiB of heap allocation. See affected SignalR versions and fixes.

Give me the TL;DR
CVE-2026-92707: MessagePack-CSharp Memory Exhaustion via SignalR

CVE-2026-92707 is a Medium-severity denial-of-service flaw in MessagePack-CSharp, the MessagePack serializer for .NET, scored 5.3 by GitHub (CNA) with vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L. The maintainers published the advisory (GHSA-qhrr-8q5h-9q3h) on September 17, 2026. Microsoft followed with its own advisory for ASP.NET Core SignalR (GHSA-86xp-94pg-8r6r) on October 13, 2026, and the CVE was published on October 15, 2026. Every MessagePack release before 2.5.303, and 3.0.0 through 3.1.8, is affected. When untrusted data is deserialized as System.Object, PrimitiveObjectFormatter allocates an object[] for each declared array length before the depth limit rejects the input. Upstream fixed it in 2.5.303 and 3.1.9. Microsoft's SignalR MessagePack protocol package on .NET 6 and .NET 7 depends on MessagePack 2.1.90 and has no OSS fix; NES (Never-Ending Support) for .NET 6.0.47 resolves it on .NET 6 by moving that dependency to MessagePack 2.5.307.

Affected and unsupported? See NES for .NET.

What is CVE-2026-92707?

CVE-2026-92707 is classified as CWE-1325: Improperly Controlled Sequential Memory Allocation. The affected component is PrimitiveObjectFormatter, the formatter MessagePack-CSharp uses when it deserializes data into object rather than a concrete type.

The bug is an ordering problem. When the formatter reads an array header, it allocates an object[] sized to the length the header declares, then descends into the elements. The configured maximum object-graph depth does eventually stop a deeply nested payload, but only after every level above it has already allocated its array.

The library does check each declared length against the bytes remaining in the buffer. The flaw is that nested array headers can reuse the same trailing unread bytes to pass that check. Each level claims a large array, each level passes validation against the same remaining buffer, and each level's array stays alive until the depth exception unwinds the stack.

The advisory's example: a payload of about 31.5 KiB drives roughly 114.7 MiB of allocation on x64, an amplification of about 3,800x.

NVD lists the CVE as Awaiting Analysis, so the GitHub (CNA) score above is the authoritative one for now.

Exploitation requires two things:

  • The application deserializes attacker-controlled MessagePack data through PrimitiveObjectFormatter. That means deserializing to object, deserializing a type with object-typed members, or using a resolver path that selects this formatter.
  • The attacker can submit payloads repeatedly. A single request causes a spike. Sustained requests cause the garbage-collection churn and heap pressure that take a service down.

The known remote path is ASP.NET Core SignalR with AddMessagePackProtocol() enabled and a reachable hub method that takes an object parameter. That path is unauthenticated only if the hub is. Hubs behind authorization keep their authorization requirements.

One detail worth noticing: SignalR's default MaximumReceiveMessageSize is 32 KB. The advisory's 31.5 KiB example payload fits under that default, so the stock message-size limit does not block it.

What an attacker can do with CVE-2026-92707

  • Send a sub-32 KB message to a SignalR hub method with an object parameter and force more than 100 MiB of managed-heap allocation per invocation.
  • Repeat the request across one or many connections to drive constant full (Gen2) garbage collections, since arrays this large land on the large object heap, raising latency for every client the process serves.
  • Push the process past its memory limit (container memory cap, App Service plan limit, or host memory), causing an OutOfMemoryException or an orchestrator kill, which drops every active SignalR connection on that instance.
  • Hit any other API, queue consumer, or cache layer that deserializes untrusted MessagePack into object with the same payload shape. SignalR is the documented path, not the only one.

CVE-2026-92707 does not disclose data or allow code execution. The impact is availability only.

Which MessagePack and SignalR versions are affected by CVE-2026-92707?

You are affected if any of these resolve to a vulnerable MessagePack version, either as a direct PackageReference or transitively through Microsoft's SignalR MessagePack protocol package:

The SignalR rows are the ones most teams miss. Microsoft's advisory (GHSA-86xp-94pg-8r6r) lists Microsoft.AspNetCore.SignalR.Protocols.MessagePack 8.0.0 through 8.0.31, 9.0.0 through 9.0.20, and 10.0.0 through 10.0.12 as affected, fixed in the October 13, 2026 servicing releases (8.0.32, 9.0.21, and 10.0.13), which raise the MessagePack floor to 2.5.303. .NET 11 previews through 11.0.0-rc.1 are also affected, fixed in rc.2. The .NET 6 and .NET 7 packages still depend on MessagePack 2.1.90, and both runtimes are past end of life (.NET 6 on November 12, 2024, and .NET 7 on May 14, 2024, per the .NET support policy), so Microsoft will not update those packages. NES for .NET 6.0.47 (released October 13, 2026) moves the .NET 6 SignalR MessagePack protocol to MessagePack 2.5.307. Blazor Server also compiles its own copy of MessagePack's reader into the ASP.NET Core shared framework; HeroDevs' investigation found the vulnerable formatter is not reachable through that copy, and 6.0.47 updates it anyway.

To check what you actually resolve, run dotnet list package --include-transitive and look for MessagePack below 2.5.303 (or between 3.0.0 and 3.1.8).

If you cannot patch immediately, the advisory lists these mitigations:

  • Stop deserializing untrusted data into System.Object, including object-typed members. Concrete types never reach PrimitiveObjectFormatter.
  • For SignalR, change object hub parameters to concrete types, disable the MessagePack hub protocol if JSON is acceptable, or put affected hub methods behind authorization.
  • Apply per-connection rate limits and cap concurrent connections per client.
  • Lowering MessagePackSecurity.MaximumObjectGraphDepth or the transport message size reduces the worst-case allocation, but it is defense in depth, not a fix. The allocations still happen before the depth check fires.

Related MessagePack-CSharp CVEs

CVE-2026-92707 is the same failure mode as the June 2026 MessagePack-CSharp batch we covered in MessagePack-CSharp Patches 12 CVEs Affecting .NET 6 and SignalR: the deserializer letting attacker-declared sizes drive allocation before validation. The closest siblings:

The June fixes (2.5.301 and 3.1.7) do not cover CVE-2026-92707. If you patched for that batch and stopped, you are still exposed.

Taking action on CVE-2026-92707

If you control your MessagePack version, move to 2.5.303 or 3.1.9 or later (2.5.303 release, 3.1.9 release) and you are done.

The harder case is SignalR. On .NET 6 and .NET 7, Microsoft's SignalR MessagePack package depends on the vulnerable 2.1.90 and no upstream update is coming. On .NET 6, NES for .NET 6.0.47 already resolves CVE-2026-92707 by moving that dependency to MessagePack 2.5.307. On .NET 8 and .NET 9, the October 13 servicing release fixes it, but both runtimes reach end of life on November 10, 2026, so the next MessagePack advisory after that date will land with no upstream fix at all.

NES for .NET provides secure, drop-in replacements for end-of-life .NET runtimes and the dependencies they ship with, so teams that cannot move to .NET 10 on Microsoft's schedule keep receiving security fixes.

Table of Contents
Author
Greg Allen
Chief Technology Officer
Open Source Insights Delivered Monthly