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