MessagePack-CSharp Typeless Deserialization Bypass, CVE-2026-48517 (Medium) -DC-Jun2026-652

Listen to this Post

How CVE-2026-48517 Works

MessagePack-CSharp is a high-performance binary serializer for C applications. It offers a “typeless” serialization feature via MessagePackSerializer.Typeless, TypelessObjectResolver, and related resolvers, which allows polymorphic deserialization where type information is embedded in the payload itself. This is useful for scenarios where the exact type is not known at compile time.
To mitigate the risk of deserializing untrusted data, MessagePack-CSharp provides a safety mechanism: MessagePackSerializerOptions.ThrowIfDeserializingTypeIsDisallowed(Type). This function allows developers to define a policy that blocks specific dangerous types (often called “gadgets”) from being instantiated during deserialization.
However, versions of MessagePack-CSharp prior to 2.5.301 and 3.1.7 contain a critical flaw in how this safety check is applied. The default implementation of the type-disallow check only inspects the outermost type name. It does not recursively inspect the types of elements inside arrays, the underlying types of nullable types, or the type arguments of constructed generic types.
This creates a straightforward bypass: an attacker can take a blocked dangerous type (e.g., System.CodeDom.Compiler.TempFileCollection) and wrap it inside an innocuous container like an array (BlockedType[]) or a generic type (List<BlockedType>). The outer type check passes because the array or list itself is not on the blocklist. The formatter machinery then proceeds to deserialize the payload and materializes a formatter for the inner blocked type, instantiating it without the safety check ever being applied.
Because typeless deserialization is already a high-risk feature for untrusted data, the presence of this disallowed-type hook creates a false sense of security. An attacker who can supply a typeless `ext-100` payload (the MessagePack extension type used for typeless data) can bypass the blocklist and instantiate prohibited types, leading to potential remote code execution or other severe consequences depending on the application’s context and the gadget types available.

DailyCVE Form

Platform: .NET
Version: <2.5.301, <3.1.7
Vulnerability: Deserialization of Untrusted Data (CWE-502)
Severity: Medium
date: 2026-06-23

Prediction: 2026-07-07

What Undercode Say

Analytics and technical details for security researchers and defenders:

Detecting Vulnerable Versions

Check your project's MessagePack package version
dotnet list package --outdated | grep MessagePack
Alternatively, inspect the .csproj file
cat YourProject.csproj | grep -i "MessagePack" -A 2 -B 2

Proof of Concept (C)

using MessagePack;
using System;
using System.Collections.Generic;
// Assume "DangerousGadget" is a type on the application's blocklist
public class DangerousGadget
{
public string Command { get; set; }
// ... potentially dangerous methods
}
// The payload wraps the dangerous type inside a List<T>
var payload = new List<DangerousGadget>
{
new DangerousGadget { Command = "calc.exe" }
};
// Serialize the payload using typeless serialization
byte[] bytes = MessagePackSerializer.Typeless.Serialize(payload);
// Deserialize the payload on a vulnerable system
// The outer type check sees List<DangerousGadget> and allows it.
// The inner DangerousGadget type is then instantiated without a check.
var result = MessagePackSerializer.Typeless.Deserialize(bytes);

Understanding the ext-100 Payload Format

A typeless MessagePack payload uses the extension type 100 (0x64)
You can inspect a raw payload using a hexdump tool
hexdump -C payload.msgpack | head -20

Exploit

An attacker exploits this vulnerability by crafting a typeless MessagePack payload where a dangerous, blocklisted type is nested inside an allowed wrapper type (array, generic list, nullable, etc.). The steps are:
1. Identify a Gadget: The attacker finds a class within the target application’s dependencies that can be abused (e.g., for file writes, command execution, or information disclosure).
2. Bypass the Blocklist: The attacker wraps this gadget type inside a harmless container, such as `Gadget[]` or List<Gadget>.
3. Serialize and Deliver: The attacker serializes this wrapper object using MessagePackSerializer.Typeless.Serialize(), creating a binary `ext-100` payload.
4. Trigger Deserialization: The attacker sends this payload to the target application, which deserializes it using a vulnerable version of the library.
5. Instantiation: The library’s formatter successfully instantiates the inner gadget type, executing its constructor, property setters, or other side effects, leading to a security breach.

Protection

1. Patch Immediately (Recommended)

Upgrade to a patched version of the library. The fix is available in version 2.5.301 and version 3.1.7.

dotnet add package MessagePack --version 2.5.301
or
dotnet add package MessagePack --version 3.1.7

2. Avoid Typeless Deserialization for Untrusted Data

The safest mitigation is to avoid using the typeless feature (MessagePackSerializer.Typeless, TypelessObjectResolver) when deserializing data from untrusted sources. Use concrete types (Deserialize<T>) instead.

3. Implement a Strict Allowlist

If typeless deserialization is unavoidable, implement a custom allowlist that explicitly approves only the types your application expects. Crucially, this allowlist must recursively validate all nested types, including array elements, generic arguments, and nullable underlying types, to prevent the bypass described in this CVE.

4. Use `MessagePackSecurity`

Configure `MessagePackSerializerOptions` with `MessagePackSecurity` settings to limit object graph depth and other potential denial-of-service vectors, reducing the attack surface.

Impact

  • Bypass of Security Controls: The primary impact is the complete bypass of the `ThrowIfDeserializingTypeIsDisallowed` safety mechanism. Applications that rely on this feature to block dangerous types are left vulnerable.
  • Remote Code Execution (RCE): If a suitable gadget (e.g., a class that executes commands in its constructor or setter) exists in the application’s dependencies, an attacker can achieve remote code execution.
  • Data Exfiltration and Tampering: Depending on the gadget available, an attacker could read sensitive files, modify data, or perform unauthorized actions within the application’s security context.
  • False Sense of Security: The presence of the type-disallow check creates a false sense of security, leading developers to believe they are protected when they are not.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top