Aug 14, 2026·5 min read·34 visits
Unsafe reflection and dynamic instantiation in mchange-commons-java's JavaBeanObjectFactory allows attackers to trigger SSRF and JNDI injection via crafted object references.
A JNDI Injection and Deserialization Gadget vulnerability exists in mchange-commons-java prior to version 0.6.0. The com.mchange.v2.naming.JavaBeanObjectFactory component permits arbitrary class instantiation and setter invocation, allowing attackers to perform Server-Side Request Forgery (SSRF) and remote class loading.
The Java library mchange-commons-java provides naming and serialization utilities. Prior to version 0.6.0, the library contains an unsafe JNDI ObjectFactory implementation named com.mchange.v2.naming.JavaBeanObjectFactory. This component dynamically instantiates arbitrary Java classes and modifies their properties through Java reflection.\n\nBy leveraging this factory, attackers can force target applications to instantiate arbitrary classes present on the classpath. If the targeted application performs JNDI lookups on untrusted inputs, or deserializes untrusted data that wraps a JNDI reference, arbitrary code execution or server-side request forgery can occur.\n\nThe vulnerability is exacerbated by the ReferenceIndirector utility. This class permits non-serializable objects to serialize themselves as reference records. Upon subsequent deserialization, the application resolves these reference records, triggering the class loader and reflection mechanisms within JavaBeanObjectFactory automatically.
The root cause lies within the dynamic initialization process of com.mchange.v2.naming.JavaBeanObjectFactory. When JNDI attempts to resolve a reference associated with this factory, the getObjectInstance method accepts any fully qualified class name specified by the reference. The factory then instantiates this class using raw reflection via standard class loaders without restriction.\n\nFollowing instantiation, the factory uses Java Introspection to locate writable properties of the class. It matches the address fields from the naming reference to the class's property descriptors and invokes the corresponding setter methods. This behavior allows attackers to pass arbitrary string arguments to arbitrary setters on any parameterless constructor class within the application's classpath.\n\nAdditionally, the factory supports deserializing raw binary properties through SerializableUtils.fromByteArray(). If an address field contains serialized binary data, the factory deserializes it automatically. This exposes the application to nested deserialization vulnerabilities if any dependency on the classpath contains a deserialization gadget chain.
An inspection of the source code before version 0.6.0 shows that JavaBeanObjectFactory performs no validation on the target class name. The following code fragment illustrates the vulnerable path:\n\njava\n// Vulnerable Code Path\nString fqcn = ref.getClassName();\nClass beanClass = Class.forName(fqcn);\nObject bean = beanClass.newInstance();\n\nBeanInfo bi = Introspector.getBeanInfo(beanClass);\nPropertyDescriptor[] pds = bi.getPropertyDescriptors();\nfor (PropertyDescriptor pd : pds) {\n Method setter = pd.getWriteMethod();\n // Setter is invoked with user-supplied arguments from JNDI RefAddr\n setter.invoke(bean, new Object[] { value });\n}\n\n\nThe patched version introduces a strict validation step in getObjectInstance to ensure the class name matches a preconfigured whitelist. The updated implementation in version 0.6.0 resolves the issue as shown below:\n\njava\n// Patched Code Path in 0.6.0\nString fqcn = ref.getClassName();\nPropertiesConfig pcfg = (cfgFinder != null ? cfgFinder.findCurrentConfig() : null);\n// Added validation to block unauthorized class names\nReferenceableUtils.ensureWhitelistedJavaBeanClass( fqcn, pcfg );\nClass beanClass = Class.forName( fqcn );\n\n\nFurthermore, the binary deserialization path in handleDeserializeBinaryRefAddressContent has been modified to disable direct deserialization of BinaryRefAddr elements by default, replacing the action with a warning message.
Exploitation requires an attacker to inject a malicious JNDI Reference into an active naming directory service or serialize a ReferenceIndirector instance. In a typical scenario, the attacker configures the reference to use com.mchange.v2.naming.JavaBeanObjectFactory as the object factory and targets javax.swing.JEditorPane as the class to instantiate.\n\nTo construct the gadget chain, the attacker defines two attributes in the reference: contentType set to text/html, and text set to an HTML payload containing a link to a remote stylesheet. When the library resolves this reference, it instantiates JEditorPane, sets the content type to HTML, and writes the payload to the text setter.\n\nmermaid\ngraph LR\n A["JNDI Lookup / Deserialization"] --> B["JavaBeanObjectFactory Instantiates JEditorPane"]\n B --> C["Invoke setContentType('text/html')"]\n C --> D["Invoke setText('HTML with stylesheet link')"]\n D --> E["Internal XML/HTML Parser requests remote CSS"]\n E --> F["SSRF to Attacker Server"]\n\n\nThis sequence causes the internal parser of the application server to perform an outbound HTTP GET request to retrieve the stylesheet. This results in Server-Side Request Forgery, enabling attackers to verify the vulnerability, map internal systems, or potentially extract internal configuration data.
The security impact of this vulnerability is high, carrying a CVSS score of 7.1. Although the attack vector is restricted to adjacent network configurations in typical deployments, successful exploitation compromises the confidentiality, integrity, and availability of the system.\n\nBecause the gadget allows arbitrary class instantiation, attackers can alter the internal state of classes on the classpath. When chained with other existing vulnerabilities or specific environment configurations, this primitive can lead to remote code execution within the security context of the JVM.\n\nThe ReferenceIndirector smuggling mechanism means that standard Java deserialization points are also vulnerable, making it a powerful vehicle for exploitation. Applications that deserialize untrusted streams are vulnerable even if they do not directly expose JNDI lookup endpoints.
The primary remediation strategy is upgrading mchange-commons-java to version 0.6.0 or higher. This version implements strict whitelisting of allowed JavaBean classes and disables insecure deserialization of binary properties by default.\n\nIn addition to upgrading, administrators must explicitly define the whitelist of allowed classes using system properties. If no whitelist is specified, the library blocks all reference resolutions and throws a NamingException.\n\nbash\n# Example of configuring a secure whitelist of Java Bean classes\n-Dcom.mchange.v2.naming.referenceableJavaBeanClassWhitelist=com.example.AllowedBeanOne,com.example.AllowedBeanTwo\n\n\nAdministrators must also ensure that remote factory location resolution remains disabled. This is controlled via the supportReferenceRemoteFactoryClassLocation system property, which should be explicitly set to false in the JVM startup parameters.
CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
mchange-commons-java swaldman (mchange) | < 0.6.0 | 0.6.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-502, CWE-470 |
| Attack Vector | Adjacent Network |
| CVSS Score | 7.1 (CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| Exploit Status | None (No public exploits available) |
| CISA KEV Status | Not Listed |
| Affected Versions | < 0.6.0 |
The product deserializes untrusted data without sufficiently verifying that the resulting data will be valid, or uses externally-controlled input to select classes or code for dynamic execution.
A heap-based buffer overflow vulnerability in Pillow PyPI binary wheels (versions 11.1.0 to 12.x) allows remote code execution or application crash via crafted JPEG 2000 files processed by the bundled libopenjp2 library.
CVE-2026-109618 (dubbed PHP2Shell) is a critical vulnerability in the PHP engine core resulting from improper out-of-memory exception handling via longjmp(). When request allocation fails mid-processing, non-local control flow bypasses cleanup procedures, leaving memory structures uninitialized or in a use-after-free state during request shutdown.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.