JEP411: Missing use-case: Monitoring / restricting libraries

Peter Firmstone peter.firmstone at zeus.net.au
Wed May 5 20:54:30 UTC 2021


On 5/05/2021 10:55 pm, Sean Mullan wrote:
> -bcc jdk-dev
> -cc security-dev
>
> On 5/5/21 12:04 AM, Peter Firmstone wrote:
>
>>
>> I think we are talking past each other here.   You keep talking about 
>> untrusted code, which sounds like applets to me.  I've read and still 
>> have a copy of Li Gong's book, applets were only one of the 
>> considerations.  I am talking about authorization and access control. 
>> We use and develop distributed or p2p systems, we don't allow 
>> untrusted code to run at all, never ever, that's a dumb idea, so lets 
>> stop talking about untrusted code, we don't use that.    We do 
>> utilize dynamic downloaded code from others and use dynamic class 
>> loading, we verify this prior to loading. We check it's authorized to 
>> run before running it.  Again I repeat, we do not run untrusted code, 
>> that would allow an attacker to cause denial of service etc, the JVM 
>> has no control over badly behaving code.
>
> But you use self-signed certificates to sign the code that will be 
> run. There is no trust in self-signed certificates unless you have 
> previously used some out-of-band mechanism to trust the public key. I 
> still don't understand why this is not the same as running untrusted 
> code, even if the code is sandboxed. And trusting the TLS server is 
> not an equivalent basis of trust.


Yes, we have a dynamic out of band mechanism.  We authenticate the other 
party using TLS, and depending on who it is (whether Permission has been 
granted to their Principal), we dynamically grant them permission to 
load their code on our system.  They can use a self signed certificate 
on their code, and we dynamically grant permission for the code signed 
by that certificate to be loaded, otherwise they can use a cryptographic 
checksum, so we can be sure their code hasn't been modified by a third 
party, it just simplifies the process, so we don't have to introduce 
another CA, we are actually trusting the remote end to audit their own 
code because we know who they are (configuration concerns).   We also 
give that code Permission to connect to the remote end of the TLS 
connection, because threads only run with one Subject, we need the code 
to represent the remote Principal.  We are not concerned with the names 
of classes or packages in their code as that is their implementation 
concern.

Provided there is no data theft, if something is taken down by badly 
behaving software, it has a level of fault tolerance, services will be 
restarted automatically, if they fall over, they are re-activated.  We 
don't use RMI's activation implementation, but we do depend on some 
activation API classes.

The problem with removal of access control is we would be permitting 
unrestricted access to a trusted third party, who doesn't require 
unrestricted access, nor is it in our interests to allow it.

It's a matter of trusting the TLS enpoint, both clients and servers are 
authenticated.   But these may just be servers talking to each other, 
not necesarilly a client server relationship, for example a client of a 
service may require an event notification, so it passes a Remote object 
as a parameter to the service, now the server of the service, is also a 
client, when it sends the event notification to listeners.  It's 
distributed, p2p.  This is used by some as a cluster back end for JEE, 
although I must admit I don't know many of the details there.

One of the reasons SecurityManager didn't control many Java 
Serialization vulnerabilities, is because ObjectInputStream was granted 
AllPermission as it was a platform class.  Clearly ObjectInputStream 
belonged in an unprivileged domain. Also it's not good that Java 
serialization circumvents invariant checks that constructors perform.

Our software also allows the company we are dealing with for example, to 
provide their own GUI window within a GUI so to to speak, to allow a 
supplier to be integrated in to the system, as an example.  That us if 
it's a system with user interaction, otherwise it could be an automated 
process between two systems, based on an agreed interface.

The only thing known prior are the Java interfaces used for intra system 
communication, the platform software (which we try to maintain as 
backward compatible) and the principal of the other party which we have 
granted permission to.

Also I have been developing a public api for serialization (we've 
discussed the de-serialization component of it previously), which is 
suitable for other serialization protocols as well as Java's. We don't 
support circular links in serialized object graphs.  The only class we 
found that required a circular link was Throwable and we have found it's 
possible to program around circular links.   Developers implementing it 
use an annotation and implement a public constructor for 
de-serialization, a public static method for serialization and another 
public static method that defines the parameter arguments for 
serialization, which are wrapped by a common serialization parameter 
type.   Permission must be granted to allow serialization to be 
implemented (this is required by the serialization protocol 
implementation) and different permission is required to serialize, the 
parameters passed to these methods require a permission for their creation.

The first serialization protocol implemented is compatible with Java's 
Serialization protocol, and for now, we can use the same serial form, to 
ease transition.

To use this system, doesn't require a physics degree, and you don't need 
a billion dollar particle accelerator, because we don't need to turn 
lead into gold, this is all just Java, basically POJO domain driven 
design style programming.   We've simplified the permissions systems to 
Principals, but dynamically grant to code, so that administrators don't 
have to.   Jar files declare a list of permission required and we have a 
tool to determine those permissions at testing time.  The actual 
permissions granted is the intersection of the permissions allowed and 
the permissions requested.   The set of permissions allowed typically 
have a wider scope, or are more permissive than those requested.

We reduced complexity with dynamic permission grants and we improved 
performance by writing our on policy implementation. Developers do need 
to preserve the Subject across threads in their code.

We use a remote invocation system / protocol, that's similar in 
principle to RMI, but unlike RMI, it preserves the Subject across secure 
network connections and it can be configured to use other Serialization 
protocols.  So serialization protocols are becoming an administration 
concern.   Unlike RMI, class resolution is determined by ClassLoader's 
at each endpoint, not a duplicate class resolution mechanism, so it also 
works on systems that use graph class resolution, rather than a 
hierarchical class loading system, eg OSGi.

These systems are also capable of dynamically discovering each other, 
even on global networks using IPv6 dynamic discovery, provided 
Principal's are known in advance.

Remember Jini and Javaspaces?  We've had twenty years to simplify it and 
address some fundamental issues, this is modern well maintained code.   
We do depend on some classes that will be removed from Java, which 
originate from Java RMI's API, like the Remote interface and 
RemoteException, but that's life I guess.  We will have to break 
backward compatibility to replace them.

That's probably why it sounds like you need a Physics degree and 
particle accelerator to do these things, because we have made things 
that would be otherwise very difficult, possible and simple enough for 
practical application.

One of the things that isn't clear, is functionality provided by Java's 
module system how it will be used to replace SecurityManager, is how 
this will work with OSGi module systems. To date, I've considered the 
Java module system as a platform concern and systems like OSGi as an 
application concern.   We produce OSGi bundles, in software releases, 
but we don't depend on OSGi.  OSGi's been around a lot longer, we may 
consider producing Java modules also, but we are waiting to learn best 
practices, because it's still relatively young.

It does appear that we might not be able to support Java past version 17 
assuming this JEP goes ahead, which seems likely.  But that might not 
matter, if enough software has the same difficulty, then perhaps support 
for Java 17 will be extended.   If we had many years, we will probably 
find a solution, but in 8 years, I'm not sure it's long enough.  You 
only need to look at how long it took for Project Jigsaw (over 10 years 
wasn't it? ) to be implemented to realise some things take a long time 
to implement, especially low level pervasive systems.

Oracle's a pretty big ship, I don't think these decisions were made in 
haste, but judging by conversations so far, the decision is a done deal, 
not a proposal, it seems unlikely this ship will be turned around.   No 
doubt there will be other use cases that come to light.

Thanks for your time and thanks for asking.

-- 
Regards,
  
Peter Firmstone
Zeus Project Services Pty Ltd.




More information about the security-dev mailing list