JEP 486 dynamic code loading

Peter Firmstone peter.firmstone at zeus.net.au
Tue Oct 15 11:31:52 UTC 2024


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20241015/9cbebe67/attachment.htm>


More information about the security-dev mailing list