Now, if we try to deserialize the already serialized object, we will get InvalidClassException ; why? We get it because, by default, the JVM associates a version number to each serializable class to control the class versioning.
It is used to verify that the serialized and deserialized objects have the same attributes and thus are compatible with deserialization. The version number is maintained in a field called serialVersionUID. If we change our class structure, e. That's why we get the exception, but if you really think about it, why should it be thrown just because I added a field? Couldn't the field just be set to its default value and then written out next time?
Yes, it can be done by providing the serialVersionUID field manually and ensuring it is always the same. It is highly recommended that each serializable class declares its serialVersionUID as the generated one is compiler dependent and thus may result in unexpected InvalidClassExceptions.
The JVM has full control for serializing the object in the default serialization process, but there are lots of downsides to using the default serialization process, some of which are:. But we can override this the default serialization behavior inside our Java class and provide some additional logic to enhance the normal process.
This can be done by providing two methods, writeObject and readObject , inside the class that we want to serialize:. Declaring both methods as private is necessary public methods will not work , so rather than the JVM, nothing else can see them. This also proves that neither method is not inherited nor overridden or overloaded.
The JVM automatically checks these methods and calls them during the serialization-deserialization process. The JVM can call these private methods, but other objects can not.
Thus, the integrity of the class is maintained and the serialization protocol can continue to work as normal. Even though those specialized private methods are provided, the object serialization works the same way by calling ObjectOutputStream.
The call to ObjectOutputStream. First, the object is checked to ensure it implements Serializable , and then, it is checked to see whether either of those private methods is provided. If they are provided, the stream class is passed as the parameter to these methods, giving the code control over its usage.
We can call ObjectOutputStream. Those calls do what they sound like — they perform the default writing and reading of the serialized object, which is important because we are not replacing the normal process; we are only adding to it. Those private methods can be used for any customization you want to make in the serialization process, e. They could be used to add extra data to the stream, perhaps a company versioning code, the possibilities are truly limitless. Suppose we have a class that got the serialization capability from its parent, which means our class extends from another class that implements Serializable.
It means anybody can serialize and deserialize the object of our class. But what if we do not want our class to be serialized or deserialized? For example, what is our class is a singleton and we want to prevent any new object creation? How setting an Object to null help Garbage Collection? How do objects become eligible for garbage collection?
How to calculate date difference in Java Difference between Path and Classpath Is Java "pass-by-reference" or "pass-by-value"?
Difference between static and nonstatic methods java Why Java does not support pointers? What is package in Java? What are wrapper classes? What is singleton class in Java? Can a top level class be private or protected in java Are Polymorphism , Overloading and Overriding similar concepts? Why can't a Java class be declared as static?
Why does Java not support operator overloading? How to generate random integers within a specific range in Java What's the meaning of System. What is the purpose of Runtime and System class? What is finally block in Java? What is difference between final, finally and finalize? What is try-with-resources in java? What is a stacktrace? An attacker searches for a gadget that is usable for launching an attack and chains several executions that end with arbitrary code execution, for instance.
In our example:. For a more real-life example, take a look at the implementation of java. It is good to know that whatever gadget chains are available in your application, is not related to your code. Although creating such a malicious gadget chain is very hard and labor-intensive, Java deserialization vulnerabilities are a genuine and dangerous security risk.
The best way to prevent a Java deserialize vulnerability is to prevent Java serialization overall. If your application does not accept serialized objects at all, it cannot harm you. However, if you do need to implement the Serializable interface due to inheritance, you can override the readObject , as seen below, to prevent actual deserialization. If your application relies on serialized objects, you can consider inspecting your ObjectInputStream before deserializing.
A library that can help you with this is the Apache Commons IO library. This library provides a ValidatedObjectInputStream where you can explicitly allow the objects you want to deserialize. Now you prevent that unexpected types are deserialized at all.
A tool like ysoserial is also extremely useful in finding Java deserialize vulnerabilities in your code. It is a tool that generates payload to discover gadget chains in common Java libraries that can, under the right conditions, exploit Java applications performing unsafe deserialization of objects.
Although this article merely focuses on this part, the same vulnerabilities exist in serialization or marshaling frameworks that handle this for you. This means that the same problems exist. To prevent these kinds of Java deserialize vulnerabilities in your external libraries, scan your libraries with Snyk Open Source early on and often.
All articles. Application Security. Ecosystems Engineering. Brian Vermeer December 18, What is serialization in Java? What is deserialization in Java? How does Java serialization work?
0コメント