Suppose I have two HashMap
s: hashMapFoo
and hashMapBar
.
I create some object objCake
and put
it into both maps, so each map has a reference to objCake
, and when I make some changes to objCake
whichever map I access it from, I get correct state of my object.
After I serialize both maps and deserialize them, I meet problem that my object objCake
has become two different objects! I change its state in hashMapFoo
, but nothing happens in hashMapBar
. hashMapBar
does not contain the correct reference any more!
All maps and objects implement Serializable
.
Can anyone please explain?
Unfortunately, the features of these native deserialization mechanisms can be repurposed for malicious effect when operating on untrusted data. Attacks against deserializers have been found to allow denial-of-service, access control, and remote code execution (RCE) attacks.
Deserialization is the process of reconstructing a data structure or object from a series of bytes or a string in order to instantiate the object for consumption. This is the reverse process of serialization, i.e., converting a data structure or object into a series of bytes for storage or transmission across devices.
Serialization is a mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process where the byte stream is used to recreate the actual Java object in memory. This mechanism is used to persist the object. The byte stream created is platform independent.
A Java deserialize vulnerability is a security vulnerability that occurs when a malicious user tries to insert a modified serialized object into the system in order to compromise the system or its data. Think of an arbitrary code execution vulnerability that can be triggered when deserializing a serialized object.
Works for me:
public class MapSerializationTest {
private static class Foo implements Serializable {
}
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
Map<String, Foo> map1 = new HashMap<String, Foo>();
map1.put("foo", foo);
Map<String, Foo> map2 = new HashMap<String, Foo>();
map2.put("foo", foo);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(map1);
oos.writeObject(map2);
oos.close();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
map1 = (Map<String, Foo>) ois.readObject();
map2 = (Map<String, Foo>) ois.readObject();
System.out.println(map1.get("foo") == map2.get("foo")); // prints true
}
}
Show us your code. You probably call reset()
on the ObjectOutputStream between the first and the second map. Or you use two difference ObjectOutputStream instances.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With