CVE-2017-20189 is a critical severity (CVSS 9.8) deserialization flaw in Clojure before 1.9.0. Classes in the Clojure jar can be used to build a serialized object that runs code when it is deserialized. It matters if a server deserializes untrusted objects. Upgrade to 1.9.0 or later.
What's affected
Clojure before 1.9.0. The Clojure issue tracker entry CLJ-2204 is marked completed with fix version Release 1.9, and Maven Central lists 1.9.0 as a release.
The record is clear about the condition: the risk applies if a server deserializes untrusted objects. An application that never deserializes data from outside its trust boundary is not exposed through this route. Per the issue text, the problem also reaches proxy classes created by users, not only classes in the Clojure jar.
The weakness is CWE-502, deserialization of untrusted data. The NVD vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. The sources I read do not give a different rating, so there is no severity conflict. The condition above is the caveat on the 9.8.
How to check if you're exposed
Find which Clojure version your project resolves. For a Maven project:
mvn dependency:tree -Dincludes=org.clojure:clojure
For Leiningen:
lein deps :tree | grep clojure
For the Clojure CLI:
clojure -Stree | grep org.clojure/clojure
For Gradle, list the runtime classpath and look for org.clojure:clojure. Any version below 1.9.0 is in scope. Check transitive dependencies too, since other libraries often bring Clojure in.
Then ask the second question: does anything in this service deserialize Java objects from a network, queue, cache or file that outsiders can influence? If not, the exposure is low even on an old version.
What to do now
- Upgrade Clojure to 1.9.0 or later, and rebuild artifacts and container images.
- Look for Java native serialization on any input you do not control, and replace it with a data format that does not instantiate arbitrary classes, such as JSON or EDN.
- If you must keep Java serialization, apply a deserialization filter that allows only the classes you expect.
- Rebuild any user defined proxy classes against the new version, since the issue text says they were also susceptible.
- Keep a dependency inventory so you can answer a question like this quickly for every service.
Why it matters
Java deserialization rebuilds objects from bytes. If an attacker controls the bytes, they choose which classes are built and how. Some classes run code while they are being rebuilt. The issue text for CLJ-2204 explains that proxy classes compiled into the Clojure jar carry a map of method names to functions, which made them usable for this purpose, and noted that this could lead to organizations blocking the Clojure jar altogether.
The fix, per the upstream commit titled "Disable serialization of proxy classes", changes how proxy classes serialize. Detailed construction steps exist in public places, and I am leaving them out on purpose. This CVE is not on the CISA Known Exploited Vulnerabilities list, and none of the sources I read says it was exploited in the wild.
Safeguard's free in-browser dependency scan at gold.safeguard.sh/scan lists the open source packages in a project and flags known vulnerabilities, which helps when you are not sure what a codebase pulls in. A reachability check helps you decide which findings apply.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
Which Clojure version fixes CVE-2017-20189?
Clojure 1.9.0. The upstream issue CLJ-2204 lists Release 1.9 as the fix version.
Am I exposed if I never deserialize untrusted data?
The record frames the risk around servers that deserialize untrusted objects. If nothing in your service does, exposure is low, but upgrading is still the clean fix.
Sources
Last reviewed: 19 October 2026.