Low level hooks in JDK for instrumentation of permission checks.

Peter Firmstone peter.firmstone at zeus.net.au
Thu Jun 10 06:40:14 UTC 2021


Just a quick question, would it be possible that some JFR hooks might 
also be useable for an authorisation layer?

Regards,

Peter.

On 9/06/2021 11:35 am, Peter Firmstone wrote:
>
> Apologies in advance if this seems like paranoid security.
>
> As you are likely now aware, we have been using SecurityManager a 
> little differently than recommended as we adapted it to our requirements.
>
> Sometimes it's not always easy to explain or obvious why something is 
> done in a certain way.
>
> It's clear we can use StackWalker to implement AccessController 
> functionality.  And it's also clear we can use ThreadLocal or Scope 
> Local's to preserve the user Subject across threads.
>
> Going forward we will need low level hooks in the JDK for our 
> authentication layer, clearly this is an opportunity to further 
> simplify and improve our authentication layer.
>
> Because we use a remote service architecture, with proxy's, the 
> proxy's are dynamically granted permission's after Service 
> Authentication, these permissions also require the user principal to 
> be logged in, we may have a number of services on the stack, for 
> example to participate in a transaction.
>
> We have a tool to generate least privilege policy files.
>
> There are two reasons we do this:
>
>  1. Simplicity of administration and auditing of policy files.
>  2. Limit the permissions of code, and grant certain permissions to
>     users to ensure users are authenticated before allowing data parsing.
>
> An example of item two, is our services require users to be logged in 
> to ensure that any data provided by the user is a trusted data source 
> (we still check the data).   We re-implemented a subset of Java 
> Serialization and have a DeSerializationPermission, which is granted 
> to Principals of users.
>
> If a user is not logged in, data cannot be de-serialized, because the 
> code alone doesn't have permission to do so.
>
> Hopefully modules and packages will have strong encapsulation in 
> future so we don't need permission's like java.lang.RuntimePermission 
> "accessClassInPackage.*"  No doubt we will need to create our own 
> Permission's.
>
> We would like to be able to limit data parsing, like XML or Java 
> de-serialization, to logged in users only.
>
> We don't break encapsulation, in future we will only use reflection to 
> call public methods and constructors (we are currently in the process 
> of doing so).   Our build systems use Maven, our build is modular.
>
> I would also like to request that all JDK modules be given 
> ProtectionDomain's <INSERT> with CodeSource's for modules with 
> meaningful URL's jrt:java.* or jrt:jdk.* </INSERT> following 
> SecurityManager deprecation.  Currently some modules have null 
> ProtectionDomain's to show they have AllPermission. However we don't 
> grant AllPermission to code in practise, we like to grant certain 
> Permission's to Principal's, not code, where the Principal is the 
> source of data, indicating the user has been authenticated and we only 
> grant what's necessary and no more.
>
> Examples of permission's granted to JDK modules in POLP policy files, 
> taken from a test harness:
>
> grant codebase "jrt:/jdk.security.jgss"
> {
>     permission java.lang.RuntimePermission 
> "accessClassInPackage.sun.security.util";
>     permission java.security.SecurityPermission 
> "putProviderProperty.JdkSASL";
> };
>
> grant codebase "jrt:/jdk.crypto.mscapi"
> {
>     permission java.lang.RuntimePermission 
> "accessClassInPackage.sun.security.util";
>     permission java.lang.RuntimePermission "loadLibrary.sunmscapi";
>     permission java.security.SecurityPermission 
> "putProviderProperty.SunMSCAPI";
> };
>
> grant codebase "jrt:/jdk.localedata"
> {
>     permission java.lang.RuntimePermission 
> "accessClassInPackage.sun.util.locale.provider";
>     permission java.lang.RuntimePermission 
> "accessClassInPackage.sun.util.resources";
> };
>
> grant codebase "jrt:/jdk.security.auth"
> {
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\lib\\jiniharness.jar", 
> "read";
>     permission javax.security.auth.AuthPermission "modifyPrincipals";
>     permission javax.security.auth.AuthPermission 
> "modifyPrivateCredentials";
>     permission javax.security.auth.AuthPermission 
> "modifyPublicCredentials";
>     permission java.lang.RuntimePermission 
> "accessClassInPackage.sun.security.krb5";
>     permission java.lang.RuntimePermission 
> "accessClassInPackage.sun.security.util";
>     permission java.lang.RuntimePermission "getProtectionDomain";
> };
>
> Example of POLP grant to code with principal, code alone cannot access 
> these, in case you are wondering, we use this to secure the RMI 
> Registry using stateless TLSv1.3, it's used by our Service Watchdog, 
> or Service Activation framework called Phoenix, it's the sole use we 
> have of the Java RMI JRMP protocol, in cases where this isn't used we 
> can disable Java Serialization completely:
>
> grant codebase 
> "file:/C:/Users/peter/Documents/NetBeansProjects/JGDMS/JGDMS/dist/target/JGDMS-3.1.1-SNAPSHOT/lib/jgdms-rmi-tls-3.1.1-SNAPSHOT.jar",
>     principal javax.security.auth.x500.X500Principal "CN=Phoenix"
> {
>     permission java.util.PropertyPermission 
> "javax.net.ssl.trustStore", "read";
>     permission java.util.PropertyPermission 
> "javax.net.ssl.trustStorePassword", "read";
>     permission java.util.PropertyPermission 
> "javax.net.ssl.trustStoreType", "read";
>     permission java.util.PropertyPermission 
> "org.apache.river.jeri.ssl.jceProvider", "read";
>     permission java.util.PropertyPermission 
> "org.apache.river.jeri.ssl.jsseProvider", "read";
>     permission java.util.PropertyPermission 
> "org.apache.river.jeri.ssl.secureRandomAlgorithm", "read";
>     permission java.util.PropertyPermission 
> "org.apache.river.jeri.ssl.sslProtocol", "read";
>     permission java.util.PropertyPermission 
> "org.apache.river.jeri.ssl.trustManagerFactoryAlgorithm", "read";
>     permission java.io.FilePermission "harness\\trust\\truststore", 
> "read";
>     permission java.net.SocketPermission "localhost:1098", 
> "listen,resolve";
> };
>
> If we really want to get into detail, instances of GrantPermission 
> shows the permissions that are granted dynamically, in this case you 
> can see that provided the Mahalo Service is run with it's principal 
> CN=Mahalo, it has permission to de-serialize a MarshalledObject (it 
> doesn't actually unmarshall it though, it uses it for equals 
> comparison), the GrantPermission shows that it grants permission to 
> de-serialize (ATOMIC, which means atomic input validation, prior to 
> object creation), after authenticating the proxy's service.
>
> grant codebase 
> "file:/C:/Users/peter/Documents/NetBeansProjects/JGDMS/JGDMS/dist/target/JGDMS-3.1.1-SNAPSHOT/lib/mahalo-service-3.1.1-SNAPSHOT.jar",
>     principal javax.security.auth.x500.X500Principal "CN=Mahalo"
> {
>     permission org.apache.river.api.io.DeSerializationPermission 
> "MARSHALL";
>     permission java.util.PropertyPermission 
> "org.apache.river.qa.home", "read";
>     permission org.apache.river.phoenix.dl.MonitorPermission 
> "net.jini.activation.arg.ActivationMonitor.inactiveObject";
>     permission net.jini.security.AuthenticationPermission 
> "javax.security.auth.x500.X500Principal \"CN=Mahalo\"", "connect";
>     permission net.jini.security.AuthenticationPermission 
> "javax.security.auth.x500.X500Principal \"CN=Mahalo\"", "listen";
>     permission net.jini.security.AuthenticationPermission 
> "javax.security.auth.x500.X500Principal \"CN=Mahalo\" peer 
> javax.security.auth.x500.X500Principal \"CN=Tester\"", "accept";
>     permission java.net.SocketPermission "DESKTOP-R0ORPA2", "resolve";
>     permission java.net.SocketPermission "DESKTOP-R0ORPA2.lan", "resolve";
>     permission java.net.SocketPermission "DESKTOP-R0ORPA2:9082", 
> "connect,resolve";
>     permission java.net.SocketPermission 
> "[fe80:0:0:0:9ca0:dfeb:b9a7:96fd%16]:1024-", "connect,resolve";
>     permission java.net.SocketPermission 
> "[fe80:0:0:0:9ca0:dfeb:b9a7:96fd%16]:1024-", "accept,resolve";
>     permission java.net.SocketPermission "localhost:0", "listen,resolve";
>     permission net.jini.security.GrantPermission 
> "net.jini.security.AuthenticationPermission 
> \"javax.security.auth.x500.X500Principal \\\"CN=Mahalo\\\" peer 
> javax.security.auth.x500.X500Principal \\\"CN=Phoenix\\\"\", 
> \"connect\";";
>     permission net.jini.security.GrantPermission 
> "net.jini.security.AuthenticationPermission 
> \"javax.security.auth.x500.X500Principal \\\"CN=Mahalo\\\" peer 
> javax.security.auth.x500.X500Principal \\\"CN=Tester\\\"\", 
> \"connect\"; net.jini.security.AuthenticationPermission 
> \"javax.security.auth.x500.X500Principal \\\"CN=Mahalo\\\" peer 
> javax.security.auth.x500.X500Principal \\\"CN=Outrigger\\\"\", 
> \"connect\";";
>     permission net.jini.security.GrantPermission 
> "org.apache.river.api.io.DeSerializationPermission \"ATOMIC\"; 
> org.apache.river.api.io.DeSerializationPermission \"MARSHALL\"; 
> org.apache.river.api.io.DeSerializationPermission \"ATOMIC\"; 
> java.lang.RuntimePermission \"accessClassInPackage.com.sun.proxy\", 
> \"\";";
>     permission javax.security.auth.AuthPermission "getSubject";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\AppData\\Local\\Temp\\-", "delete";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\AppData\\Local\\Temp\\-", "read";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\AppData\\Local\\Temp\\-", "write";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\JGDMS\\dist\\target\\JGDMS-3.1.1-SNAPSHOT\\lib-dl\\mahalo-dl-3.1.1-SNAPSHOT.jar", 
> "read";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\JGDMS\\dist\\target\\JGDMS-3.1.1-SNAPSHOT\\lib\\mahalo-service-3.1.1-SNAPSHOT.jar", 
> "read";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\mahalo.keystore", 
> "read";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\outrigger.keystore", 
> "read";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\phoenix.keystore", 
> "read";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\reggie.keystore", 
> "read";
>     permission java.io.FilePermission 
> "C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\tester.keystore", 
> "read";
>     permission java.lang.RuntimePermission "getClassLoader";
>     permission java.lang.RuntimePermission "modifyThread";
>     permission net.jini.discovery.DiscoveryPermission 
> "QATestDefaultGroup_DESKTOP-R0ORPA2_1623111918992";
> };
>
> -- 
> Regards,
>   
> Peter Firmstone
> Zeus Project Services Pty Ltd.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20210610/a6c5cdce/attachment.htm>


More information about the security-dev mailing list