Skip to content

Commit 7f7fb58

Browse files
ledoyensbrannen
authored andcommitted
Deprecate SerializationUtils#deserialize
Since SerializationUtils#deserialize is based on Java's serialization mechanism, it can be the source of Remote Code Execution (RCE) vulnerabilities. Closes gh-28075
1 parent e681e71 commit 7f7fb58

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ private static CacheOperationInvoker.ThrowableWrapper rewriteCallStack(
150150
@Nullable
151151
private static <T extends Throwable> T cloneException(T exception) {
152152
try {
153-
return (T) SerializationUtils.deserialize(SerializationUtils.serialize(exception));
153+
return SerializationUtils.clone(exception);
154154
}
155155
catch (Exception ex) {
156156
return null; // exception parameter cannot be cloned

spring-core/src/main/java/org/springframework/util/SerializationUtils.java

+17
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.IOException;
2222
import java.io.ObjectInputStream;
2323
import java.io.ObjectOutputStream;
24+
import java.io.Serializable;
2425

2526
import org.springframework.lang.Nullable;
2627

@@ -57,8 +58,13 @@ public static byte[] serialize(@Nullable Object object) {
5758
* Deserialize the byte array into an object.
5859
* @param bytes a serialized object
5960
* @return the result of deserializing the bytes
61+
* @deprecated This utility uses Java's reflection, which allows arbitrary code to be
62+
* run and is known for being the source of many Remote Code Execution vulnerabilities.
63+
* <p>Prefer the use of an external tool (that serializes to JSON, XML or any other format)
64+
* which is regularly checked and updated for not allowing RCE.
6065
*/
6166
@Nullable
67+
@Deprecated
6268
public static Object deserialize(@Nullable byte[] bytes) {
6369
if (bytes == null) {
6470
return null;
@@ -74,4 +80,15 @@ public static Object deserialize(@Nullable byte[] bytes) {
7480
}
7581
}
7682

83+
/**
84+
* Clone the given object using Java's serialization.
85+
* @param object the object to clone
86+
* @param <T> the type of the object to clone
87+
* @return a clone (deep-copy) of the given object
88+
* @since 6.0.0
89+
*/
90+
@SuppressWarnings("unchecked")
91+
public static <T extends Serializable> T clone(T object) {
92+
return (T) SerializationUtils.deserialize(SerializationUtils.serialize(object));
93+
}
7794
}

spring-core/src/test/java/org/springframework/util/SerializationUtilsTests.java

+5
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,9 @@ void deserializeNull() throws Exception {
6767
assertThat(SerializationUtils.deserialize(null)).isNull();
6868
}
6969

70+
@Test
71+
void cloneException() {
72+
IllegalArgumentException ex = new IllegalArgumentException("foo");
73+
assertThat(SerializationUtils.clone(ex)).hasMessage("foo").isNotSameAs(ex);
74+
}
7075
}

0 commit comments

Comments
 (0)