Security
Jun 29, 2026

CVE-2026-48109: Out-of-Bounds Read in MessagePack for .NET LZ4

How a crafted LZ4 payload forces out-of-bounds reads during MessagePack decompression and crashes the process

Give me the TL;DR
CVE-2026-48109: Out-of-Bounds Read in MessagePack for .NET LZ4
For Qualys admins, NES for .NET directly resolves the EOL/Obsolete Software:   Microsoft .NET Version 6 Detected vulnerability, ensuring your systems remain secure and compliant. Fill out the form to get pricing details and learn more.

On June 11, 2026, the MessagePack-CSharp maintainers disclosed CVE-2026-48109 (GHSA-hv8m-jj95-wg3x), a High-severity out-of-bounds read in the MessagePack NuGet package. GitHub, acting as the CNA, scored it 8.2 (CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H), CWE-20 (Improper Input Validation). The flaw lives in the optional LZ4 decompression path: a crafted payload with manipulated LZ4 token and length fields forces reads past the end of the compressed input buffer, throwing an AccessViolationException and terminating the process. It affects every 2.x release before 2.5.301 and 3.x releases from 3.0.214-rc.1 up to 3.1.7, and it is fixed in MessagePack 2.5.301 and 3.1.7. CVE-2026-48109 is also the anchor of a wider cluster: eight MessagePack advisories landed in June 2026, and the rest are covered in the Related CVEs section below. The catch for enterprises: if you pull MessagePack transitively through an end-of-life .NET runtime, the supported path to that fix is closed.

Running .NET 6 or another end-of-life .NET line? See NES for .NET.

What is CVE-2026-48109?

CVE-2026-48109 is an out-of-bounds read (CWE-20: Improper Input Validation) in the LZ4 decompression path that MessagePack uses for its Lz4Block and Lz4BlockArray compression modes.

MessagePack is a binary serialization format, and the MessagePack NuGet package (MessagePack-CSharp) is the de facto implementation for .NET. When LZ4 compression is enabled, the library decompresses the payload before deserializing it. The decoder is built on a deprecated fast-decompression routine that does not take a source-length bound. That missing bound is the bug.

When an attacker sends a payload whose internal LZ4 token and length fields are manipulated, the decoder reads past the end of the compressed input buffer. In practice that surfaces as an AccessViolationException during decompression, which crashes the hosting process. Under some conditions, data that gets over-read before the crash can result in limited, unintended memory disclosure, which is why the vector carries a low confidentiality impact.

The condition that matters: the application deserializes untrusted MessagePack data with LZ4 compression turned on.

Severity and exploit conditions

GitHub (the CNA) and NVD agree on this one: both label CVE-2026-48109 High. The score reflects an unauthenticated, network-reachable crash. The one real precondition is that LZ4 compression is enabled on a path that accepts untrusted input. If your application only ever decompresses payloads from a strongly trusted producer, the practical exposure is lower, but on any public or semi-trusted boundary this is a clean denial-of-service primitive.

What an attacker can do

The attack is a single crafted MessagePack payload sent to any code path that decompresses untrusted input with Lz4Block or Lz4BlockArray enabled. Concretely:

  • Crash a SignalR hub. ASP.NET Core's MessagePack hub protocol deserializes client-supplied frames. A malicious client frame can take down the process serving every connected user.
  • Crash an MVC endpoint. Any ASP.NET Core action that reads MessagePack request bodies with LZ4 compression is reachable by an unauthenticated HTTP client.
  • Crash a background consumer. Services that pull LZ4-compressed MessagePack off a queue, cache, or message bus will fault when they hit the poisoned message, and depending on retry logic may fault repeatedly.
  • Read a little memory it should not. Before the AccessViolationException, over-read bytes can leak into error paths or responses, a limited but real confidentiality concern.

Because the failure is an AccessViolationException rather than a catchable parse error, the typical try/catch around deserialization will not save the process. The host goes down.

Who is affected? (the MessagePack package)

The vulnerability lives in the MessagePack NuGet package, so exposure tracks the package version, not your .NET version directly.

The package-level fix is open source and available. If you reference MessagePack directly in your project, the remediation is a one-line version bump to 2.5.301 (v2 line) or 3.1.7 (v3 line). Do that today.

The harder problem is transitive exposure on an unsupported runtime, which is the next section.

The .NET 6 problem: a fixed dependency you cannot reach

Most teams do not reference MessagePack directly. They inherit it. ASP.NET Core's SignalR MessagePack hub protocol (Microsoft.AspNetCore.SignalR.Protocols.MessagePack) depends on the MessagePack package, and the version is pinned by the framework you target.

On the .NET 6 servicing line, that pin is the problem. The final .NET 6 release of the SignalR MessagePack protocol package, 6.0.36, depends on MessagePack 2.1.90, which sits well below the 2.5.301 fix and is exposed to the entire June 2026 cluster. .NET 6 reached end of life on November 12, 2024. Microsoft no longer ships serviced ASP.NET Core packages for the .NET 6 line, so there is no future 6.0.x release that will bump the transitive MessagePack to a patched version. The supported path to the fix is closed.

A .NET 6 application can still add a top-level MessagePack 2.5.301 reference to override the transitive pin. That works for this specific dependency. But it is a manual override on a runtime that stopped receiving security servicing more than a year ago, which means the MessagePack cluster is one example of a growing backlog of unpatched platform-level risk, not a one-off you can paper over.

Related CVEs: the full June 2026 MessagePack cluster

CVE-2026-48109 is the headline, but seven more MessagePack advisories were published on June 25, 2026. They share the same fix versions (2.5.301 and 3.1.7) and the same untrusted-deserialization threat model. If you are remediating one, remediate all eight.

There is a scoring split worth understanding. The MessagePack maintainers scored most of the cluster as Medium using CVSS v4.0, where the AT:P (Attack Requirements: Present) and AC:H (Attack Complexity: High) metrics reflect their judgment that exploitation needs particular configurations. NVD ran its own CVSS v3.1 analysis and rated them higher, treating them as low-complexity network denial of service. We show both so you can reconcile against whichever source your tooling ingests.

The standout is CVE-2026-48509, which NVD scored 9.1 Critical (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H) against the maintainers' 6.3 Medium. It is ASP.NET Core-specific: the parameterless MessagePackInputFormatter() constructor resolves to MessagePackSecurity.TrustedData, which is exactly the wrong posture for HTTP request bodies that cross a trust boundary. If you register new MessagePackInputFormatter() without explicitly passing untrusted-data options, an unauthenticated client can drive algorithmic-complexity denial of service through colliding keys.

The pattern across the cluster is consistent: untrusted MessagePack input plus a parsing or allocation path that skips the library's own depth, allocation, or collision protections, ending in process termination. CVE-2026-48506 (uncatchable StackOverflowException via TrySkip()) is the broadest, because skipping unknown or ignored fields happens during ordinary deserialization, not just in exotic configurations.

For broader .NET 6 context, see our prior coverage of CVE-2026-32178, an SMTP injection in System.Net.Mail that left .NET 6 without a patch, and the .NET EncryptedXml denial-of-service in CVE-2026-26171. The MessagePack cluster is the same story in a different dependency: a supported fix exists upstream, but the EOL runtime never carries it to you.

Mitigation guidance

Taking action

CVE-2026-48109 is a clean illustration of how end-of-life runtimes turn a routine dependency fix into an unreachable one. The MessagePack maintainers shipped the patch. Supported .NET lines pick it up through normal servicing. But .NET 6 reached end of life in November 2024, so the SignalR MessagePack pin stays frozen at 2.1.90, and this cluster joins the growing list of platform-level CVEs that no longer have a supported remediation path on that runtime.

If your organization still runs .NET 6 in production, and many do because migration is expensive and risky, you are accumulating exposure like this on every servicing cycle you miss. NES for .NET provides secure, drop-in serviced builds for end-of-life .NET lines, including the patched dependencies behind vulnerabilities like the June 2026 MessagePack cluster, so you stay protected and compliant while you plan a move to a supported LTS on your own timeline. With .NET 8 reaching end of life in November 2026, that coverage already extends to the next line about to go dark.

See pricing or talk to our team to scope coverage for your .NET estate.

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