Make your code unserializable and undeserializable
Serializing is an outdated way of storing the state of an object. The current Java documentation encourages the use of XML as a replacement.[21] However, since serialization may still be implemented as a way to retain backwards compatibility it is a valid issue to discuss. Serializing breaks your code into an external byte array that stores the state of the class as well as the state of variables in the class. This byte array stores only the necessary information for reconstructing an instance of the object in the same state. This method can be used to store instances of an object and restore them at a later time. [15]
Although, when the object is stored it is in an unprotected byte array. This byte array can then be examined by anyone who has access to the disk space that is being used to store it in. In the case where your application is being distributed, this is the hard disk of the end-user. Even if the storage space of the array is inaccessible it is possible for the output stream of the serialization to be monitored.[14] With access to the serialized object in its byte array form, it is possible to ascertain the values of any of the variables. All public and private variables can be examined. If one of these variables is a reference to another object that is serializable, all of that objectsÕ fields are also stored in the byte array.
To prevent this your class must be designated as unserializable. The solution of not implementing the serializable interface is not sufficient, as a subclass could do this. To properly prevent the serialization of your code you must implement the serializable interface and have the requisite writeObject() method throw a class nonserializable exception.[2] Code for this follows:
private final void writeObject(ObjectOutputStream out)
throws java.io.IOException {
throw new java.io.IOException("Object cannot be serialized");
}
In a related problem it is important for a class to be undeserializable as well. To deserialize an object the readObject() method as defined in the serializable interface is called. This takes a byte array as generated by the writeObject() method and translates it back into an object of the stored state. This is a necessary if your class is serializable, it must be possible to return from the byte array for serialization to be a useful feature.
This process also causes some security concerns. There is no way to insure that the byte array that you are deserializing contains a valid copy of the object. It is possible for someone to generate a byte array that is a valid serialization of an object of your class. This byte array can then contain any values that the creator wishes for any of the variables. This gives the creator of the byte array complete control of the state of the object, making it possible for them to modify any value in the object possibly creating an object in an insecure state. In addition it is possible to use this method to create as many instances of a particular class as desired. This is a security problem if the class is used in a way where its uniqueness is assumed. Such an example would be a duplicate security manager or multiple username/password databases.
This problem can be solved in a nature similar to the serialization problem. It is inadequate to not implement the serializable interface and assume the problem is solved. You must also throw an exception when deserialization is attempted.[2] Code for this follows:
private final void readObject(ObjectInputStream in)
throws java.io.IOException {
throw new java.io.IOException("Object cannot be deserialized");
}