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