Aug 14, 2026·5 min read·6 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.
Grav CMS prior to version 1.7.53 and 2.0.0-rc.8 is vulnerable to an unauthenticated remote denial of service (DoS) vulnerability. By supplying crafted query parameters with extremely large dimensions to image assets, remote unauthenticated attackers can force the server to allocate massive amounts of system memory, leading to kernel Out-Of-Memory (OOM) termination of web worker processes.
CVE-2026-53657 is a local privilege escalation vulnerability in Lima (lima-vm/lima) affecting versions prior to 2.1.3 when configured with the QEMU driver. The guest agent daemon, running as root, creates its communication socket `/run/lima-guestagent.sock` with world-writable permissions (0777). This allows unprivileged local users to command the agent to establish arbitrary tunnels, including to privileged local UNIX sockets (like D-Bus). Because the target daemon authenticates the incoming connection using the credentials of the root-owned guest agent (via SO_PEERCRED), unprivileged users can perform root operations, resulting in complete guest VM compromise.
An unauthenticated Denial of Service vulnerability exists in the s2n-quic library's CryptoStream reassembler due to a lack of buffer limits on out-of-order cryptographic frames. An attacker can transmit a crafted CRYPTO frame with an extremely high offset and nominal payload, forcing the receiver to execute unbounded memory allocations and causing service crashes.
SurrealDB versions supporting element-level SELECT permissions on arrays are vulnerable to a logical authorization bypass. Due to an index-shifting error during array filtration, restricted elements can skip permission checks and leak to unauthorized record users.
CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists because the input validation routine fails to account for percent-encoded directory traversal sequences like '..%2f' before passing them to urllib.request.url2pathname(), which decodes them into active traversal sequences.
CVE-2026-73654 is a high-severity prototype pollution vulnerability in Trigger.dev. The flaw occurs during the handling of run-metadata updates through the PUT /api/v1/runs/:runId/metadata endpoint. Because user-supplied keys are parsed directly by the @jsonhero/path library without sanitization, an authenticated attacker with low privileges can pollute the global Object.prototype. This causes database queries via Prisma ORM to fail validation and induces unhandled exceptions in the Prometheus metrics client, resulting in a process-wide denial of service.