Hello,

This are some very interesting comments in JEP 486:

Various early Java Platform features were designed around a vision of mobile objects. They used serialization to move code and data between JVMs, and assumed applications would enable the Security Manager to defend against maliciously serialized objects.

 *

    RMI supportsdynamic code loading
    
<https://docs.oracle.com/en/java/javase/23/docs/specs/rmi/arch.html#dynamic-class-loading>,
    but it is enabled only when the Security Manager is enabled. This
    feature of RMI has been disabled by default since 2013. With the
    removal of the Security Manager, it is no longer possible to use
    this feature. We may remove it in a future release.

The above failed due to multiple issues, it's worth noting these were very difficult issue that took many years to solve, we did however solve them comprehensively.

JGDMS is a modern evolution of Jini, it uses extensible remote invocation (JERI), it's like Java RMI, but many of the problems inherent in RMI have been eliminated over many years of development:

1. Secure protocols and invocation constraints, allows administrators
   to configure the use of various encryption protocols and ensure
   these are in force prior to establishing connections.
2. Dynamic code loading, unlike Java RMI, JERI doesn't attempt to
   duplicate the role of ClassLoaders, instead ClassLoaders are
   assigned at endpoints and these are used to determine class
   visibility.   This addressed issues experienced with annotation loss
   and compatibility with OSGi.
3. Codebase annotations are not used, CodeSource's are only provided
   following authentication, the ClassLoaders at each endpoint are
   established with necessary CodeSource URL's.   This addressed
   codebase annotation loss and nightmare class resolution issues that
   plagued Jini in the early days.
4. Additionally if objects originating from a third party are
   serialized within a stream, the third party will be authenticated or
   that object cannot be deserialised, it will also be deserialised
   into a separate ClassLoader and ProtectionDomain unique to each
   originating party.
5. Distributed Garbage Collection, concurrency bugs and race conditions
   were eliminated, DGC operates using the last authenticated encrypted
   connection.
6. Authorization, during establishment of connections, both endpoints
   are authenticated and limited permissions, such as authorization of
   code to be dynamically loaded, based on a checksum of the code, or a
   signer certificate and authorization to unmarshal objects
   originating from the authenticated end points.
7. Isolation of code at endpoints based on authenticated identity.
8. Atomic serialization using constructors (does not support circular
   object graphs) using input validation prior to object
   instantiation.  Additionally endpoints must be authenticated and
   permission to deserialise granted, to the user and the code that
   performs deserialisation and input validation before it can proceed.
9. Principle of least privilege, with supporting tooling, so developers
   don't need to write policy files, instead policy files are
   generated, audited and edited during deployment.   We also have
   dynamic policy to manage permissions for remote services, their
   proxy's and users.
10. Concurrent, high scaling SecurityManager and policy provider, with
   very minimal impact on performance.
11. All hotspots eliminated.

The cause of Jini's initial failure, were class resolution issues, codebase annotation loss and IPv4 network address translation.

While this sounds complex, the software is relatively simple to use, developers can configure JERI to use insecure protocols for testing and simply reconfigure it for secure deployment.   The complexity that existed in Jini was related to bugs, which have now been solved.

The goals of Jini were realized.   Mobile objects are just parameters and returns for calls on remote services, if developers follow domain driven design principles, ensures services method calls are idempotent and parameter objects are immutable, then you couldn't ask for an easier to develop mobile object framework.

I thought it interesting to see we succeeded where others failed and nobody noticed, I guess that happens when you don't have major funding, are small, dedicated, working quietly for decades to solve some very difficult problems and don't attract attention.

Ironically Java, born of the Jini vision, is now deviating from our path, features in JGDMS are just to damn good, I'm sure we'll be using them for many years to come.

But very interesting comments, we successfully employ SecurityManager to defend against maliciously serialized objects, we do many things OpenJDK dev's think are impossible simply because it's not possible with Java implementation code like RMI, Serialization and policy provider with lack of tooling. ;)  We have permission checks in the deserialising stream, allowing administrators to ensure the remote Principal, source of the object bytes has been authenticated, while also limiting de-serialization to designated and isolated checksummed code (not every loaded class in the jvm), otherwise de-serialization doesn't proceed, I mean you must have both the code and the user principal, if you only have one of either, or there's other code on your stack, you can't deserialize, our serialization code is also hardened against gadget attacks, an attacker must first break encryption, authentication, then bypass POLP authorization and input validation (stream type checks, parameter and superclass invariant checks) before it's possible to break into the JVM, very good if you're running on OpenBSD on Sparc, not as good as if you're running on a less secure architecture, but still difficult nonetheless.

I think there's a hardened stripped down fork in our future, where trusted platform code is limited to bootstrap code.  I am grateful that OpenJDK continues development of Java, although we will no longer use official Java releases, we can still continue to benefit from OpenJDK efforts.

Atomic serialization:

https://github.com/pfirmstone/JGDMS/wiki

https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/services/reggie/reggie-dl/src/main/java/org/apache/river/reggie/proxy/RegistrarEvent.java

https://www.youtube.com/watch?v=mIbA2ymCWDs

--
Regards,
Peter

Reply via email to