Serialzation PREVIOUSLY: RFR: 8229773: Resolve permissions for code source URLs lazily

Sean Mullan sean.mullan at oracle.com
Mon Aug 19 21:55:28 UTC 2019


Brian Goetz (copied) has done a lot of thinking in the serialization 
area, so I have copied him. Not sure if you have seen it but he recently 
posted a document about some of his ideas and possible future directions 
for serialization: 
http://cr.openjdk.java.net/~briangoetz/amber/serialization.html

--Sean

On 8/17/19 10:22 PM, Peter Firmstone wrote:
> Thanks Sean,
> 
> You've gone to some trouble to answer my question, which demonstrates 
> you have considered it.
> 
> I donate some time to help maintain Apache River, derived from Sun's 
> Jini.  Once Jini depended on RMI, today, not so much, it still has some 
> dependencies on some RMI interfaces, but doesn't utilise JRMP although 
> it provides some backward compatibilty enable it.
> 
> But my point is, we heavily utilise java Serialization, and have an 
> independant implementation of a subset of Java Serialization 
> (originating from Apache Harmony).  We do this for security as we use an 
> annotated serialization constructor.   Serial form is unchanged, we have 
> Serializers for commonly used java library objects, for example, we have 
> a "PermissionSerializer", but we don't have a 
> "PermissionCollectionSerializer" or "PermissionsSerializer" (for 
> java.security.Permissions).   Incidentally, we have found we do not need 
> the ability to serialize circular object graphs.   Throwable is an 
> object that has a circular object graph, but that circular object graph 
> can be linked up after deserialization.
> 
> Permission implementing Serializable is probably not too much of a 
> threat, as these objects are effectively immutable after lazy 
> initialization.
> 
> ProtectionDomain calls java.security.Permissions::setReadOnly during 
> it's construction.
> 
> ProtectionDomain::getPermissions returns internal 
> java.security.Permissions.   If this is serialized, then the readOnly 
> internal state can be written to as the internal object references are 
> accessible from within the stream.
> 
> Admitedly, the attacker would already need to have some privilege, to 
> have access to a ProtectionDomain, so it's a path of privilege 
> escallation.  I'm not talking about gadget attacks and deserialization 
> of untrusted data, I'm talking about breaking encapsulation.
> 
> Even though we are heavily dependant on Java Serialization, we are very 
> careful when we implement it, and avoid implementing it when possible. 
> Hindsight is 20:20, but given we are now seeing some Java SE backward 
> compatibility breakages, perhaps it might be worth considering breaking 
> serialization.  I don't mean we need to necessarily break object serial 
> form, but making the Java serialization API explicit with subset of 
> existing api features, that makes long term maintenace and security less 
> of a burden and removing support for Serialization of some objects, 
> where it is seldom used, perhaps using a JEP that requests developers to 
> consider which library objects actually need to be serializable.
> 
> Something we do in our Java Serialization API is require that mutable 
> deserialized objects are defensively copied during object construction 
> (serial fields are deserialized before an object is constructed, the 
> deserialized fields are accessible via a parameter passed in during 
> construction.   We have tools that assist developers to check 
> deserialized Java Collections contain the expected object types for 
> example, so during object construction the developer has to replace the 
> Collection with a new instance and copy the contents to the new 
> Collection after checking the type of each object contained therein. 
> Also we don't actually serialize Java Collections, we have standard 
> serial forms for List, Set and Map, so these serial forms are equal, 
> similar to the List, Set and Map contracts.  By doing this, Collections 
> don't actually need to implement Serializable at all, as a Serializer 
> becomes responsible for their serialization.   This also means that all 
> Collections must be accessed by interfaces, rather than implementation 
> classes, so the deserialization constructor, must defensively copy them 
> into their preferred Collection instance.   It's a bit like dependency 
> injection.
> 
> I know it would take time, and there would be some pain, but long term 
> it would save a lot of maintenance developer time.
> 
> Regards,
> 
> Peter.
> 
> On 17/08/2019 12:50 AM, Sean Mullan wrote:
>> On 8/15/19 8:18 PM, Peter Firmstone wrote:
>>> Hi Roger,
>>>
>>> +1 for writeReplace
>>>
>>> Personally I'd like to see some security classes break backward 
>>> compatibility and remove support for serialization as it allows 
>>> someone to get references to internal objects, especially since these 
>>> classes are cached by the JVM.  Which makes 
>>> PermissionCollection.setReadOnly() very easy to bypass, by adding 
>>> permissions to internal collections once you have a reference to them.
>>>
>>> Does anyone have any use cases for serializing these objects?
>>>
>>> These objects are easy to re-create by sending or recieving and 
>>> parsing strings, because they are built from text based policy files, 
>>> and when you do that, you are validating input, so I never did fully 
>>> understand why they were made serializable.
>>
>> This is briefly explained on page 61 in the "Inside Java 2 Platform 
>> Security" book [1]:
>>
>> "The Permission class implements two interfaces: java.security.Guard 
>> and java.io.Serializable. For the latter, the intention is that 
>> Permission objects may be transported to remote machines, such as via 
>> Remote Method Invocation (RMI), and thus a Serializable representation 
>> is useful."
>>
>> The Permission class was introduced in Java SE 1.2 so there were 
>> different motivations back then :)
>>
>> --Sean
>>
>> [1] https://www.oracle.com/technetwork/java/javaee/index-141918.html
> 



More information about the security-dev mailing list