Closed cryptoad closed 3 weeks ago
Thank you @cryptoad for your report.
There seems to be no Security Policy for the Scala project, so I will just file this here.
It's overdue that we create https://www.scala-lang.org/security, you're right.
About the report, I want to repeat what I wrote on https://github.com/scala/scala/pull/10118.
In order to attack a system using the mechanism you describe, the system needs to be deserializing untrusted data that an attacker can control. Deserializing untrusted data is always a security risk, if a system does so then that is the vulnerability.
We might be able to change certain exploitable classes on our side, but we cannot address the issue in general. In your example the entry point is in TrieMap
, another example that was recently reported uses an entry point in the JDK (java.util.PriorityQueue
) which can be used to execute Function0
instances on deserialization.
A typical Scala or Java application has many thousand classfiles on the classpath. The chance that any of them implements exploitable behavior on deserialization is always high.
If a specific gadget chain can be broken without impacting functionality and code maintainability, we might do so (PRs welcome). But generally we consider the issue as not addressable on our side.
I agree with @lrytz. We should stop considering the existence of these patterns of code in classes as vulnerabilities. The only vulnerability is deserializing untrusted data with the Java serialization mechanism.
I suggested we close this ticket as "not a bug".
Understood, thank you for taking the time to answer.
Could you please point me to the PriorityQueue
issue? If anything can be done on our side, I'd like to make sure we are covered.
That chain is
java.lang.PriorityQueue.readObject
-> heapify
-> siftDownUsingComparator
-> (scala.math.Ordering$IterableOrdering: Comparator).compare
-> (scala.collection.View$$anon$1 [defined in fromIteratorProvider]: IterableOnce).iterator
-> Function0.apply
There seems to be no Security Policy for the Scala project, so I will just file this here.
This issue is akin to https://github.com/scala/scala/pull/10118, where
LazyList
could be abused to execute aFunction0
during deserialization, which was assigned CVE-2022-36944 (cc: @lrytz)TrieMap
has a few paths that could lead to the execution of aFunction1
. The most straightforward one is:scala/collection/concurrent/TrieMap.readObject(Ljava/io/ObjectInputStream;)V
scala/collection/concurrent/TrieMap.update(Ljava/lang/Object;Ljava/lang/Object;)V
scala/collection/concurrent/TrieMap.computeHash(Ljava/lang/Object;)I
scala/util/hashing/Hashing$$anon$1.hash(Ljava/lang/Object;)I
One can set a
Hashing
object in theTrieMap
with an arbitraryhash
function that will end up being executed when theTrieMap
is deserialized. It just needs to be a serializableFunction1
, and there are plenty of those with potential security implications.Other paths involve
update
+inserthc
and maybe others.Reproduction steps
The following is a PoC demonstrating the issue that was tested with Scala 2, setting
hash
tonull
:This will result in the following exception during deserialization (since the function is null):
Problem
Like for CVE-2022-36944, this means that
TrieMap
can be used as part of a gadget chain to obtain arbitrary code execution when deserializing an attacker controlled object.