This post is part of our Apache ActiveMQ® CVE guide. It explains both CVEs, why the earlier safety feature didn’t hold, which applications are exposed, how to find them, and what to change beyond the version number.
The two CVEs at a glance
| Detail | CVE-2025-54539 | CVE-2025-29953 |
| NuGet package | Apache.NMS.AMQP | Apache.NMS.ActiveMQ (OpenWire) |
| Affected | Through 2.3.0 | Before 2.1.1 |
| Fixed in | 2.4.0 (NuGet, 24 Aug 2025) | 2.1.1 (NuGet, 16 Feb 2025) |
| Disclosed | 15 Oct 2025 | 18 Apr 2025 |
| Apache severity | Important | Moderate |
| CVSS 3.1 | 9.8 Critical (CISA-ADP; NIST has not scored it) | 9.8 Critical (CISA-ADP; NIST has not scored it) |
| Weakness | CWE-502, deserialization of untrusted data | CWE-502, deserialization of untrusted data |
| Credit | Security Research Team, Endor Labs | g7shot, working with Trend Zero Day Initiative |
| Exploited | No reports; not in CISA KEV | No reports; not in CISA KEV |
Sources: Apache advisories for CVE-2025-54539 and CVE-2025-29953; NVD for CVE-2025-54539 and CVE-2025-29953; Apache.NMS.AMQP and Apache.NMS.ActiveMQ on NuGet.
The two scores tell different stories. Apache’s lower ratings reflect the precondition: the attacker must control or impersonate the server. CISA’s 9.8 reflects what happens if they do. For an application that only talks to brokers you run and secure, Apache’s view is closer. For one that connects to partner, vendor or shared brokers, treat it as critical.
Why a client-side flaw matters in Apache ActiveMQ® .NET apps
Messaging security usually assumes the broker is the asset to protect and the clients are the untrusted party. These CVEs flip the trust direction. Both advisories describe a malicious server sending crafted responses that the client deserializes, leading to code execution in the client process.
That client is typically a .NET service in the middle of a business process: an order handler, a payment worker, a logistics integration. It runs with whatever access that service has, to databases, file shares, internal APIs and credentials. A compromise there can reach further than a compromise of the broker itself.
Situations where the “malicious broker” precondition is realistic:
- Partner and vendor brokers. B2B integrations where your .NET service connects to a broker another company runs.
- A broker that is already compromised. CVE-2023-46604 and CVE-2026-34197 have both been exploited in the wild. An attacker who owns your broker can use it to reach every .NET consumer.
- Shared or multi-tenant brokers. Where producer access is loosely controlled, third-party analysis of CVE-2025-54539 shows that anyone who can publish to a queue a vulnerable client consumes may reach the same code path (SecureLayer7).
- Connections without TLS verification. If a client doesn’t verify the broker’s certificate, it can’t be sure the broker is the real one.
How the attack works: .NET binary deserialization
Both clients support object messages: a JMS-style message whose body is a serialized .NET object. To read the body, the clients use BinaryFormatter, .NET’s binary serializer. Whoever controls the bytes chooses which types get created and with what data, and certain .NET types run code as they’re rebuilt.
Microsoft’s own guidance is blunt. Its BinaryFormatter security guide says deserializing untrusted input with it is never safe, that the type can’t be made secure, and that a custom binder, the mechanism allow lists rely on, may not be enough to stop code execution.
The allow list that didn’t hold
In version 2.1.0 (2023), both clients added a deserialization policy: an allow list and a deny list of .NET types, enforced by a binder as the message body is read. It was the right idea within the constraints of BinaryFormatter.
Both CVEs are bypasses of that policy. Apache’s advisories say the lists “could be bypassed” (OpenWire) or bypassed “under certain conditions” (AMQP). One independent analysis of CVE-2025-54539 attributes it to the type check treating an unresolved type as trusted, failing open instead of closed (SecureLayer7). Apache has not published its own root-cause detail.
The default that still allows everything
Upgrading fixes the bypass. It doesn’t turn the policy on. In the current source for both clients, the default allow list is * (every type) and the default deny list is empty. Unless your application sets a policy, a fixed client still deserializes any type a broker sends in an object message.
Don’t know which of your .NET services talk to which brokers?
Who is exposed
Your application is exposed if all three are true:
- It references Apache.NMS.AMQP 2.3.0 or earlier, or Apache.NMS.ActiveMQ before 2.1.1. That includes every 1.x release.
- It consumes messages, or otherwise reads responses, from a broker that an attacker could control, compromise or impersonate.
- The deserialization path is reachable, which in practice means the application handles object messages.
The scale is real. On NuGet, Apache.NMS.ActiveMQ has about 12 million downloads, and 2.1.0, a vulnerable version, is its single most-downloaded release. Apache.NMS.AMQP has about 2.8 million. NuGet now flags every vulnerable version of both packages as critical.
Long-lived enterprise .NET estates in finance, defense and logistics are where old NMS versions tend to sit: built once against a broker, then left running for years.
How to find vulnerable Apache ActiveMQ® .NET applications
- Ask the build. In each solution, run:
- dotnet list package –vulnerable –include-transitive
It reports packages with known vulnerabilities, including ones pulled in indirectly by other libraries. Older projects that don’t use the .NET SDK project format need a manual check of packages.config.
- Search your code and dependency manifests for Apache.NMS.ActiveMQ and Apache.NMS.AMQP, and for object-message use such as IObjectMessage or CreateObjectMessage. An application that never sends or reads object messages has a much smaller attack surface, but upgrade it anyway: you can’t be sure what a malicious broker will send.
- Map client-to-broker connections. For each affected application, record which broker it connects to, who runs it, and whether TLS with certificate verification is on. That list tells you which upgrades are urgent.
How to fix it
- Upgrade. Move to Apache.NMS.AMQP 2.4.0 or later, and Apache.NMS.ActiveMQ 2.1.1 or later. As of October 2026 the latest releases are 2.4.0 and 2.3.0. Rebuild and redeploy every application, including ones that only pull the client in transitively.
- Set a deserialization policy. Both clients accept a policy on the connection, through the nms.deserializationPolicy.allowList URI option or a DeserializationPolicy on the connection factory. Set the allow list to the specific types your application expects, so a broker can’t make it create anything else. Check the exact value format in the documentation or source for your client version before rolling it out.
- Move off object messages. This is the fix that lasts. Serialize to JSON with System.Text.Json and send a text message:
| using System.Text.Json; using Apache.NMS; // Producer: send JSON text instead of a serialized .NET object var body = JsonSerializer.Serialize(order); var message = session.CreateTextMessage(body); producer.Send(message); // Consumer: read text and deserialize to a known type if (received is ITextMessage text) { var order = JsonSerializer.Deserialize<OrderPlaced>(text.Text); } |
The consumer decides the type, not the message. Apache’s own advisories recommend migrating away from .NET binary serialization, and say the project is considering removing it from the NMS API.
- Verify the broker. Use TLS and verify the broker’s certificate, so a client can’t be pointed at an impostor. Secure the brokers themselves; a broker owned through a broker-side CVE becomes the attacker’s tool against every client.
- Treat partner brokers as untrusted. For B2B integrations, isolate the consuming service, limit what it can reach, and never accept object messages across a trust boundary.
A note on .NET 9
Microsoft removed BinaryFormatter from .NET 9: it now throws an exception unless an application adds an unsupported compatibility package. Teams moving to .NET 9 or later will find object messages stop working. Test this before upgrading the runtime; the NMS projects don’t document the behavior yet. Treat that as the deadline for step 3 rather than a reason to add the compatibility package.
We’ll compare how OpenWire and AMQP differ more broadly in our upcoming Protocol Comparison guide.
Planning the move off .NET object messages?
Frequently asked questions
CVE-2025-54539 is a deserialization flaw in Apache.NMS.AMQP, the Apache ActiveMQ® .NET AMQP client, through version 2.3.0. A malicious or impersonated broker can send a crafted message that makes the client run code. It is fixed in 2.4.0. Apache rates it Important; CISA scores it 9.8.
CVE-2025-29953 is a deserialization allow-list bypass in Apache.NMS.ActiveMQ, the Apache ActiveMQ® .NET OpenWire client, before version 2.1.1. A malicious server can bypass the client’s type allow and deny lists and achieve code execution in the client. Apache rates it Moderate; CISA scores it 9.8.
No. Both flaws are in the Apache ActiveMQ® .NET client libraries that applications reference from NuGet. You must upgrade the packages in every application and redeploy. Securing the broker still matters, because a compromised broker is one way an attacker can deliver the malicious message.
Upgrading fixes the bypass, but the default policy in both clients still allows every type. Set an allow list of the types you expect, or better, stop using object messages and send JSON or text instead.
No. These advisories cover only the Apache ActiveMQ® .NET NMS clients. Java OpenWire clients had their own deserialization flaw, CVE-2023-46604, fixed in Apache ActiveMQ® 5.15.16, 5.16.7, 5.17.6, 5.18.3 and 6.0.0.
Broker patching programs rarely reach the .NET services on the other end of the connection. meshIQ’s Apache ActiveMQ® engineers find every Apache ActiveMQ® .NET client in your estate, upgrade it, and help your teams move off binary serialization before .NET 9 forces the issue.