Feb 10, 2026·6 min read·170 visits
The .NET COSE parser fails to handle CBOR 'indefinite-length' maps correctly. A loop condition comparing an integer to null evaluates to false, causing the parser to skip validating the message headers. This allows attackers to forge signatures and spoof identities.
A critical logic error in the Microsoft .NET 'System.Security.Cryptography.Cose' library allows attackers to bypass signature verification. By utilizing CBOR indefinite-length encoding, an attacker can trick the parser into skipping the Protected Header bucket entirely. This results in the acceptance of spoofed messages because critical security parameters—like the signature algorithm—are never validated.
COSE (CBOR Object Signing and Encryption) is essentially the binary, cool cousin of JSON Web Tokens (JWT). It is the backbone of modern protocols like WebAuthn (FIDO2) and various IoT security standards. When you log into a website using your fingerprint or FaceID, there's a good chance COSE is handling the cryptographic handshake under the hood.
But here is the problem: Parsing binary formats is hard. Unlike JSON, which is just text, CBOR (Concise Binary Object Representation) has multiple ways to say the same thing. You can say, "Here comes a map with 5 items," or you can say, "Here starts a map, keep reading until I say stop." That second method is called indefinite-length encoding.
CVE-2026-21218 is what happens when a developer assumes everyone plays by the first rule. It’s a spoofing vulnerability that arises not from complex buffer overflows or heap spraying, but from a simple, almost philosophical question in C#: What happens when you ask if zero is less than null?
The vulnerability lives in System.Security.Cryptography.Cose, specifically in how it parses the Protected Headers. These headers contain critical metadata, such as the alg (algorithm) used to sign the message or crit (critical) headers that the verifier must understand.
In the .NET implementation, the parser used a standard for loop to iterate through the map elements. It relied on reader.ReadStartMap() to get the number of items. Here is the catch: if the CBOR map uses indefinite-length encoding (marked by byte 0xBF), the ReadStartMap() method returns null (because the length is unknown).
The code looked something like this:
int? length = reader.ReadStartMap();
for (int i = 0; i < length; i++)
{
// Parse critical headers
}In C#, the comparison i < length when length is null evaluates to false. It doesn't throw an exception; it just silently decides the condition is not met. Consequently, the loop body—the part responsible for validating the signature algorithm and checking critical constraints—is skipped entirely. The code thinks it parsed an empty map and moves on, leaving the door wide open.
Let's look at the fix, which highlights exactly how dangerous the original logic was. The developers had to rip out the length-based for loop and replace it with a state-based while loop that actually looks at the data stream.
The Vulnerable Pattern:
// The 'length' is null for indefinite maps.
// The loop never runs. The headers are ignored.
int? length = reader.ReadStartMap();
for (int i = 0; i < length; i++)
{
DecodeHeader(reader);
}The Fixed Code (Patch 6abb139):
reader.ReadStartMap();
// Now we don't care about the length count.
// We keep reading until we hit the 'EndMap' marker.
while (true)
{
CborReaderState state = reader.PeekState();
if (state == CborReaderState.EndMap)
{
reader.ReadEndMap();
break;
}
DecodeHeader(reader);
}By checking the state of the reader (PeekState) instead of trusting a nullable integer count, the parser is forced to process every byte of the header, regardless of how the attacker encoded it. This effectively closes the bypass.
To exploit this, an attacker doesn't need to steal a private key. They just need to confuse the bouncer. Here is how a spoofing attack plays out:
CoseSign1 message.0xA1 for a map of size 1), the attacker starts the map with 0xBF (Start Indefinite Map) and immediately closes it with 0xFF (Break), or includes malicious headers inside it.The Result: The .NET parser reads the 0xBF, gets null for the length, and skips the header validation loop. It doesn't see an algorithm header. It doesn't see any critical constraints. If the application logic defaults to a specific algorithm or fails to check if headers were actually processed, it proceeds to "verify" the signature against an empty set of constraints—or worse, assumes the message is valid because no validation errors were thrown.
> [!NOTE]
> This is particularly devastating for the crit (Critical) header parameter. RFC 9052 mandates that if a crit header is present, the verifier must understand it or reject the message. By using indefinite encoding, the attacker can hide headers that would otherwise cause the message to be rejected.
This isn't just a parsing error; it's an Integrity violation of the highest order (CVSS I:H).
Identity Spoofing: If your application uses COSE for authentication (like verifying a signed token), an attacker can forge a token that looks valid to the system but was never signed by the real private key.
IoT Command Injection: Many IoT devices use COSE to sign firmware updates or command messages. An attacker could send a "Shutdown" or "Unlock" command signed by... nobody. The parser, skipping the validation logic, might accept the command as legitimate, leading to physical consequences.
Data Forgery: In financial or medical systems exchanging signed records, this allows an attacker to inject false data records that appear to be cryptographically verified.
Microsoft released the fix in the February 2026 Patch Tuesday. The remediation is straightforward: Update your .NET runtime.
Fixed Versions:
If you are manually managing NuGet packages, ensure System.Security.Cryptography.Cose is updated to the latest servicing version. For developers writing their own CBOR parsers: Never trust the length. Always implement a state-based reader that handles both definite and indefinite lengths, or explicitly reject indefinite-length encoding if your spec allows it (Canonical CBOR usually prohibits it, but parsers must be robust).
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
.NET 8.0 Microsoft | < 8.0.24 | 8.0.24 |
.NET 9.0 Microsoft | < 9.0.13 | 9.0.13 |
.NET 10.0 Microsoft | < 10.0.3 | 10.0.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-166 |
| Attack Vector | Network |
| CVSS Score | 7.5 (High) |
| Impact | Integrity Loss (Spoofing) |
| Root Cause | Logic error in indefinite-length CBOR parsing |
| Exploit Status | Plausible / Trivial Logic |
The software does not handle or incorrectly handles a missing special element, which can lead to unexpected behavior.
A high-severity access control vulnerability in ToolHive CLI before v0.30.1 and ToolHive Studio before v0.38.0 allows local containerized MCP servers to bypass network isolation. This enables malicious workloads to establish TCP/IP connections to administrative and control plane endpoints exposed on the host loopback interface.
AnyCable is a real-time communication server. Prior to version 1.6.15, its Pusher-compatible REST API suffered from an authentication bypass vulnerability because it failed to verify that the request body matched the signature-validated body_md5 parameter. This allows attackers to perform replay attacks with modified body contents.
A denial-of-service vulnerability exists in AnyIO prior to version 4.14.2. Standard error streams of process-pool workers are connected to an operating system pipe that is never drained by the parent process. This allows a worker to fill the pipe buffer and deadlock indefinitely.
CVE-2026-63349 is a critical privilege-dropping bypass vulnerability in the AnyIO asynchronous framework (versions 4.14.0 and 4.14.1) on POSIX platforms. Due to a variable assignment typo, supplementary groups specified by the developer are not correctly propagated to the execution backend, resulting in subprocesses retaining the parent process's elevated supplementary group permissions.
CVE-2026-63406 is an information disclosure vulnerability in AnyCable-go prior to version 1.6.15. The built-in telemetry client is enabled by default with a hardcoded public authentication token ('secret'). This client digests highly sensitive configuration parameters and command-line arguments, including JWT secrets and RPC secrets, into a stable SHA-256 fingerprint. This fingerprint is sent over public networks, exposing those administrative secrets to offline dictionary and brute-force attacks if intercepted.
CVE-2026-84992 is a Cross-Site Scripting (XSS) vulnerability affecting md-editor-v3 before version 6.5.4. It occurs because the fenced-code block language parser directly interpolates unescaped language metadata into unquoted HTML attributes inside the custom rendering callback. This bypasses the built-in XSSPlugin which runs during the parsing phase, before rendering.