CVE-2026-55223 Overview
CVE-2026-55223 affects the c3p0 JDBC connection pooling library in versions prior to 0.14.0. The library exposes DataSource and ConnectionPoolDataSource implementations whose getConnection() and getPooledConnection() methods match the JavaBeans getter naming convention. JavaBean introspection libraries treat these as safe property accessors while they actually invoke JDBC drivers. Attackers can chain c3p0 with a vulnerable JDBC driver and a JavaBean-resolving carrier such as an Apache commons-beanutils BeanComparator inside a serialized collection. When the target application deserializes the payload, property lookups reach the JDBC driver and trigger code execution. The maintainer resolved the flaw in c3p0 0.14.0.
Critical Impact
c3p0 serves as an essential sink in a deserialization gadget chain that can lead to arbitrary code execution when applications deserialize untrusted data with a vulnerable JDBC driver on the classpath.
Affected Products
- c3p0 JDBC connection pooling library versions prior to 0.14.0
- Applications deserializing untrusted data with a vulnerable JDBC driver on the CLASSPATH
- Systems using Apache commons-beanutils BeanComparator alongside c3p0
Discovery Timeline
- 2026-06-30 - CVE-2026-55223 published to NVD
- 2026-07-02 - Last updated in NVD database
Technical Details for CVE-2026-55223
Vulnerability Analysis
The issue is an insecure deserialization gadget composition classified under [CWE-502]. c3p0's DataSource and ConnectionPoolDataSource classes expose methods that look like standard JavaBean property accessors. JavaBean introspection APIs enumerate these methods as readable properties and invoke them during property resolution. Because those accessors actually dispatch into JDBC driver code, an attacker who controls a serialized object graph can force property resolution to reach vulnerable driver logic.
Root Cause
The root cause is the collision between JDBC's getConnection() naming and the JavaBeans getter convention. JavaBean-driven serialization carriers assume getXXX() methods are side-effect-free property reads. In c3p0, calling those getters instantiates driver-backed connections, so introspection triggers driver code paths the developer never intended to expose.
Attack Vector
Exploitation requires three components on the target classpath: a susceptible c3p0 DataSource or ConnectionPoolDataSource, a vulnerable JDBC driver, and a carrier that resolves JavaBean properties during deserialization. Attackers typically use a TreeMap or PriorityQueue paired with a commons-beanutils BeanComparator configured to sort on the connection or pooledConnection property. Deserializing the collection invokes the comparator, which walks bean properties and calls into the JDBC driver, executing attacker-controlled logic remotely over a network path.
// Patch: BeanInfo generator that excludes dangerous JDBC accessors
// Source: https://github.com/swaldman/c3p0/commit/7b022c4b6694dabc6204254dc917af9c38f2cb27
package com.mchange.v2.c3p0.beaninfo;
import java.io.*;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import com.mchange.v2.codegen.bean.BeanInfoGen;
import static java.nio.charset.StandardCharsets.UTF_8;
public final class C3P0BeanInfoGen
{
final static Set excludedPropertyNames;
final static Set excludedPropertyTypes;
static
{
Set tmp0 = new HashSet();
tmp0.add("connection");
tmp0.add("pooledConnection");
excludedPropertyNames = Collections.unmodifiableSet(tmp0);
Set tmp1 = new HashSet();
tmp1.add( java.sql.Connection.class );
tmp1.add( javax.sql.PooledConnection.class );
excludedPropertyTypes = Collections.unmodifiableSet(tmp1);
}
public static void main(String[] argv) throws Exception
{
// Generates BeanInfo that hides connection/pooledConnection
// from JavaBean introspection, closing the gadget sink.
}
}
The patch generates BeanInfo classes that hide connection and pooledConnection from JavaBean introspection, breaking the property-resolution path attackers rely on.
Detection Methods for CVE-2026-55223
Indicators of Compromise
- Unexpected outbound JDBC driver connections initiated from application processes shortly after deserialization events
- Java stack traces showing commons-beanutilsBeanComparator frames calling into c3p0 DataSource or ConnectionPoolDataSource accessors
- Presence of serialized TreeMap or PriorityQueue payloads in HTTP bodies, message queues, or cache entries handled by Java services
Detection Strategies
- Inventory application dependencies for c3p0 versions prior to 0.14.0 combined with commons-beanutils on the same classpath
- Instrument Java deserialization entry points to log class names resolved during ObjectInputStream.readObject() calls
- Alert on child processes spawned by Java application servers that host services accepting serialized input
Monitoring Recommendations
- Enable JVM flight recorder or agent-based tracing on methods DataSource.getConnection() and ConnectionPoolDataSource.getPooledConnection() invoked outside of expected pool initialization
- Forward application logs to a SIEM and correlate deserialization exceptions with subsequent JDBC activity
- Monitor egress traffic from application tiers for JDBC connections to unexpected hosts
How to Mitigate CVE-2026-55223
Immediate Actions Required
- Upgrade c3p0 to version 0.14.0 or later across all Java applications
- Audit deserialization surfaces such as RMI endpoints, JMS consumers, HTTP session stores, and cache layers for untrusted input
- Remove commons-beanutils from classpaths where it is not required, or upgrade to a version that restricts BeanComparator property resolution
Patch Information
The maintainer released the fix in c3p0 0.14.0. The change generates explicit BeanInfo descriptors that exclude the connection and pooledConnection properties from introspection, preventing JavaBean-driven carriers from reaching JDBC driver code. Review the GitHub Security Advisory GHSA-w6w4-rjh9-9r58 and the upstream commit for full remediation details.
Workarounds
- Configure a JEP 290 serialization filter (ObjectInputFilter) to reject com.mchange.*, org.apache.commons.beanutils.BeanComparator, and other unused classes from being deserialized
- Isolate services that must accept serialized Java objects behind authenticated, network-restricted transport
- Remove unused JDBC drivers from application classpaths to shrink the exploitable driver surface
# Example JVM serialization filter blocking known gadget classes
java -Djdk.serialFilter='!com.mchange.**;!org.apache.commons.beanutils.**;!org.apache.commons.collections.functors.**;maxdepth=20;maxarray=10000' \
-jar application.jar
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

