Towards better serialization

Kłeczek, Michał michal at kleczek.org
Wed Jun 12 12:23:30 UTC 2019


To be honest I fail to see anything that would make it a better 
serialization. This proposal is simply enforcement of implementing 
writeReplace()/readResolve() pair (aka classic memento pattern) with 
some syntactic sugar on top.

And while it might make serialization more secure (which I doubt - see 
below) it is not better for sure as it forces developers to do more 
work. The whole premise of Java serialization was that it is supposed to 
be transparent and cheap to implement. It is rooted in Smalltalk/Self 
and the idea of a program image and transparent state migration. Why are 
we giving this up? A better serialization should be simply a better 
implementation of this idea - what we have here is retraction instead.

What's more - it does not really address security concerns! Even the 
example of non-serializable ServerConnection being recreated based on 
serverName upon deserialization illustrates it - serverName is not 
sanitized/validated and as such is a security hole (as may lead to 
information leak) - the only real defense is SecurityManager and proper 
security policy in place.

The issue here is that we try to fix security problems in the wrong 
place. Almost all security issues with serialization are not really 
caused by serialization itself but by:
- huge classpath with all libraries accessible to each other (ie. 
deserialization gadgets availability in classpath)
- running applications with no SecurityManager (starting a JVM with no 
SecurityManager by default was the single biggest mistake Java designers 
made in the past IMHO)

There are issues with current serialization but IMHO they can be fixed 
with small adjustments to the spec/API:
- Add an @Unshared annotation on a member field - that would signal 
requirement for the deserialization framework to make sure the instance 
is unshared
- Use ObjectInput/ObjectOutput interface everywhere instead of 
ObjectInputStream/ObjectOutputStream classes (which would allow 
different easier provision of different serialization formats)
- Provide easy way to register invariants validation (right now 
registering ObjectInputValidation is a PITA) - it can be done by 
introducing @InvariantCheck annotation on a method.
- Provide an easy way to designate a constructor or a static method as a 
deserialization facility (either similar to the one in the proposal or 
taking ObjectInput as an argument)
- Make use of ObjectInputStream.GetField/ObjectOutputStream.PutField 
interfaces easier/more obvious

My point here is - current serialization offers a lot and getting rid of 
it instead of making it better is a huge step back. What's more - 
getting rid of it is in reality only moving the problem around as the 
need for transparent serialization is there and is witnessed by 
existence of all Json/XML transparent serialization solutions. They will 
not go away - quite the contrary - there will be more of them as there 
will be no default in the standard library. And they will be worse than 
the default one.



More information about the amber-dev mailing list