<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Just a quick question, would it be possible that some JFR hooks
      might also be useable for an authorisation layer?</p>
    <p>Regards,</p>
    <p>Peter.<br>
    </p>
    <div class="moz-cite-prefix">On 9/06/2021 11:35 am, Peter Firmstone
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:c2fd8f9c-050e-be6f-1b47-90314544544a@zeus.net.au">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <p>Apologies in advance if this seems like paranoid security.<br>
      </p>
      <p>As you are likely now aware, we have been using SecurityManager
        a little differently than recommended as we adapted it to our
        requirements.<br>
      </p>
      <p>Sometimes it's not always easy to explain or obvious why
        something is done in a certain way.</p>
      <p>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.</p>
      <p>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.<br>
      </p>
      <p>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.<br>
      </p>
      <p>We have a tool to generate least privilege policy files.</p>
      <p>There are two reasons we do this:</p>
      <ol>
        <li>Simplicity of administration and auditing of policy files.</li>
        <li>Limit the permissions of code, and grant certain permissions
          to users to ensure users are authenticated before allowing
          data parsing.<br>
        </li>
      </ol>
      <p>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.</p>
      <p>If a user is not logged in, data cannot be de-serialized,
        because the code alone doesn't have permission to do so.</p>
      <p>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.<br>
      </p>
      <p>We would like to be able to limit data parsing, like XML or
        Java de-serialization, to logged in users only.<br>
      </p>
      <p>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.<br>
      </p>
      <p>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.<br>
      </p>
      <p>Examples of permission's granted to JDK modules in POLP policy
        files, taken from a test harness:<br>
      </p>
      <p>grant codebase "jrt:/jdk.security.jgss"<br>
        {<br>
            permission java.lang.RuntimePermission
        "accessClassInPackage.sun.security.util";<br>
            permission java.security.SecurityPermission
        "putProviderProperty.JdkSASL";<br>
        };</p>
      <p>grant codebase "jrt:/jdk.crypto.mscapi"<br>
        {<br>
            permission java.lang.RuntimePermission
        "accessClassInPackage.sun.security.util";<br>
            permission java.lang.RuntimePermission
        "loadLibrary.sunmscapi";<br>
            permission java.security.SecurityPermission
        "putProviderProperty.SunMSCAPI";<br>
        };<br>
      </p>
      <p>grant codebase "jrt:/jdk.localedata"<br>
        {<br>
            permission java.lang.RuntimePermission
        "accessClassInPackage.sun.util.locale.provider";<br>
            permission java.lang.RuntimePermission
        "accessClassInPackage.sun.util.resources";<br>
        };</p>
      <p>grant codebase "jrt:/jdk.security.auth"<br>
        {<br>
            permission java.io.FilePermission
"C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\lib\\jiniharness.jar",
        "read";<br>
            permission javax.security.auth.AuthPermission
        "modifyPrincipals";<br>
            permission javax.security.auth.AuthPermission
        "modifyPrivateCredentials";<br>
            permission javax.security.auth.AuthPermission
        "modifyPublicCredentials";<br>
            permission java.lang.RuntimePermission
        "accessClassInPackage.sun.security.krb5";<br>
            permission java.lang.RuntimePermission
        "accessClassInPackage.sun.security.util";<br>
            permission java.lang.RuntimePermission
        "getProtectionDomain";<br>
        };<br>
      </p>
      <p>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:</p>
      <p>grant codebase
        <a class="moz-txt-link-rfc2396E"
href="file:/C:/Users/peter/Documents/NetBeansProjects/JGDMS/JGDMS/dist/target/JGDMS-3.1.1-SNAPSHOT/lib/jgdms-rmi-tls-3.1.1-SNAPSHOT.jar"
          moz-do-not-send="true">"file:/C:/Users/peter/Documents/NetBeansProjects/JGDMS/JGDMS/dist/target/JGDMS-3.1.1-SNAPSHOT/lib/jgdms-rmi-tls-3.1.1-SNAPSHOT.jar"</a>,<br>
            principal javax.security.auth.x500.X500Principal
        "CN=Phoenix"<br>
        {<br>
            permission java.util.PropertyPermission
        "javax.net.ssl.trustStore", "read";<br>
            permission java.util.PropertyPermission
        "javax.net.ssl.trustStorePassword", "read";<br>
            permission java.util.PropertyPermission
        "javax.net.ssl.trustStoreType", "read";<br>
            permission java.util.PropertyPermission
        "org.apache.river.jeri.ssl.jceProvider", "read";<br>
            permission java.util.PropertyPermission
        "org.apache.river.jeri.ssl.jsseProvider", "read";<br>
            permission java.util.PropertyPermission
        "org.apache.river.jeri.ssl.secureRandomAlgorithm", "read";<br>
            permission java.util.PropertyPermission
        "org.apache.river.jeri.ssl.sslProtocol", "read";<br>
            permission java.util.PropertyPermission
        "org.apache.river.jeri.ssl.trustManagerFactoryAlgorithm",
        "read";<br>
            permission java.io.FilePermission
        "harness\\trust\\truststore", "read";<br>
            permission java.net.SocketPermission "localhost:1098",
        "listen,resolve";<br>
        };<br>
      </p>
      <p>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.<br>
      </p>
      <p>grant codebase
        <a class="moz-txt-link-rfc2396E"
href="file:/C:/Users/peter/Documents/NetBeansProjects/JGDMS/JGDMS/dist/target/JGDMS-3.1.1-SNAPSHOT/lib/mahalo-service-3.1.1-SNAPSHOT.jar"
          moz-do-not-send="true">"file:/C:/Users/peter/Documents/NetBeansProjects/JGDMS/JGDMS/dist/target/JGDMS-3.1.1-SNAPSHOT/lib/mahalo-service-3.1.1-SNAPSHOT.jar"</a>,<br>
            principal javax.security.auth.x500.X500Principal "CN=Mahalo"<br>
        {<br>
            permission org.apache.river.api.io.DeSerializationPermission
        "MARSHALL";<br>
            permission java.util.PropertyPermission
        "org.apache.river.qa.home", "read";<br>
            permission org.apache.river.phoenix.dl.MonitorPermission
        "net.jini.activation.arg.ActivationMonitor.inactiveObject";<br>
            permission net.jini.security.AuthenticationPermission
        "javax.security.auth.x500.X500Principal \"CN=Mahalo\"",
        "connect";<br>
            permission net.jini.security.AuthenticationPermission
        "javax.security.auth.x500.X500Principal \"CN=Mahalo\"",
        "listen";<br>
            permission net.jini.security.AuthenticationPermission
        "javax.security.auth.x500.X500Principal \"CN=Mahalo\" peer
        javax.security.auth.x500.X500Principal \"CN=Tester\"", "accept";<br>
            permission java.net.SocketPermission "DESKTOP-R0ORPA2",
        "resolve";<br>
            permission java.net.SocketPermission "DESKTOP-R0ORPA2.lan",
        "resolve";<br>
            permission java.net.SocketPermission "DESKTOP-R0ORPA2:9082",
        "connect,resolve";<br>
            permission java.net.SocketPermission
        "[fe80:0:0:0:9ca0:dfeb:b9a7:96fd%16]:1024-", "connect,resolve";<br>
            permission java.net.SocketPermission
        "[fe80:0:0:0:9ca0:dfeb:b9a7:96fd%16]:1024-", "accept,resolve";<br>
            permission java.net.SocketPermission "localhost:0",
        "listen,resolve";<br>
            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\";";<br>
            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\";";<br>
            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\", \"\";";<br>
            permission javax.security.auth.AuthPermission "getSubject";<br>
            permission java.io.FilePermission
        "C:\\Users\\peter\\AppData\\Local\\Temp\\-", "delete";<br>
            permission java.io.FilePermission
        "C:\\Users\\peter\\AppData\\Local\\Temp\\-", "read";<br>
            permission java.io.FilePermission
        "C:\\Users\\peter\\AppData\\Local\\Temp\\-", "write";<br>
            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";<br>
            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";<br>
            permission java.io.FilePermission
"C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\mahalo.keystore",
        "read";<br>
            permission java.io.FilePermission
"C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\outrigger.keystore",
        "read";<br>
            permission java.io.FilePermission
"C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\phoenix.keystore",
        "read";<br>
            permission java.io.FilePermission
"C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\reggie.keystore",
        "read";<br>
            permission java.io.FilePermission
"C:\\Users\\peter\\Documents\\NetBeansProjects\\JGDMS\\qa\\harness\\trust\\tester.keystore",
        "read";<br>
            permission java.lang.RuntimePermission "getClassLoader";<br>
            permission java.lang.RuntimePermission "modifyThread";<br>
            permission net.jini.discovery.DiscoveryPermission
        "QATestDefaultGroup_DESKTOP-R0ORPA2_1623111918992";<br>
        };<br>
      </p>
      <pre class="moz-signature" cols="72">-- 
Regards,
 
Peter Firmstone
Zeus Project Services Pty Ltd.</pre>
    </blockquote>
  </body>
</html>