<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Clarification inline below<br>
    </p>
    <div class="moz-cite-prefix">On 4/05/2021 8:35 am, Peter Firmstone
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:b1c17718-0c97-61c4-e3aa-7e638f8279f8@zeus.net.au">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <div class="moz-cite-prefix">On 4/05/2021 5:12 am, Sean Mullan
        wrote:<br>
      </div>
      <blockquote type="cite"
        cite="mid:64985afa-1d8b-cc6c-3283-4fd4ef0f5d1a@oracle.com">-bcc
        jdk-dev <br>
        -cc security-dev <br>
        <br>
        On 4/30/21 10:04 PM, Peter Firmstone wrote: <br>
        <blockquote type="cite"><SNIP><br>
          <br>
          In our software we use a ProtectionDomain to represent a
          remote server, because a thread only runs with the user's
          Subject (and that Subject must be carefully preserved for
          other threads), there is no way to represent the remote
          Server's Subject in a local domain , other than with a
          ProtectionDomain. Â  Our software is peer to peer, clients can
          be servers and servers can also be clients.  Code to interact
          with the server is downloaded via Maven and loaded.  Any
          permission's granted to a user, are injected into the stack
          when run as the client Subject, to authenticate the user for
          the server and establish a secure connection, calls made by
          the client are run with the user's Subject on the server,
          again for access control purposes.  This functionality is
          beyond the capability of Java RMI, we aren't using Java RMI to
          do this.  This is very important to allow us to make fine
          grained access control decisions, or perform event
          notification callbacks over secure connections, without this
          feature, we can't make a secure connection with a callback,
          and you know what happens when you have to do something, but
          cannot do it securely?   We only grant network access directly
          back to the server, downloaded code has been verified and is
          not expected to cause denial of service, by consuming
          resources etc, but we don't want to grant third party access
          to files, or random network connections, we still have privacy
          obligations for third party information. <br>
          <br>
          We can allow a third party to use unsigned certificates to
          sign their jar files or use a checksum and we verify them
          using a secure connection to the server, prior to loading.  
          We then dynamically grant permissions to the server's self
          signed Certificate (used to sign the jar file), or a
          ProtectionDomain, after authenticating the server and
          receiving a check sum or certificate from it.  So the client
          authenticates the server using signed TLS certificates (EG by
          letsencrypt.org or a trusted CA). We use self signed
          certificates on Jar files if we sign them, we are actually
          trusting the server entity in this case, eg a trusted company,
          but also placing restrictions on them. <br>
        </blockquote>
        <br>
        I am probably missing something, but I don't understand how this
        is secure if you are using TLS server certificates as the basis
        for authenticating signed code. These are two very different use
        cases. <br>
      </blockquote>
      <p><br>
        Clarifying the level of trust:</p>
      <ol>
        <li>You have a trusted party, whom you trust to write their own
          code.</li>
        <li>You run that code on your systems dynamically.</li>
        <li>You trust the other party, but you either haven't or it's
          not practical to audit their code.</li>
        <li>Using the principle of least privilege, you limit the
          ability of the other party's code to ensure they are unable
          observe data they shouldn't, eg a third party with whom you
          also do business.</li>
        <li>While a trusted party (eg a supplier) could write code that
          caused denial of service, eg using up all available memory,
          there is no motivation for them to do so.  However there may
          be motivation for them to see quotes on your system from
          another supplier if they have access to it.</li>
      </ol>
      <p>The code is loaded dynamically, but before the jvm loads it, we
        authenticate the party that is asking us to load their code,
        after which we are basically asking them the question, is this
        the code you want us to load?  Please check that it hasn't been
        tampered with.   The trusted party gives us a checksum, or a
        self signed certificate they used to sign the jar, we are then
        satisfied that we have received the software unaltered from the
        trusted party and not a MITM attack, so we load it.   However we
        limit the permission of this software using the principle of
        least privilege.   They don't get file permissions, they are
        only allowed to connect to the server they used to authenticate
        with.  If a third party uses the same jar file, they don't gain
        the permissions granted to other parties, as it will be loaded
        into a separate ClassLoader with the permissions granted to that
        party only.<br>
      </p>
    </blockquote>
    <p>Just to clarify, these are software logic interactions.<br>
    </p>
    <blockquote type="cite"
      cite="mid:b1c17718-0c97-61c4-e3aa-7e638f8279f8@zeus.net.au">
      <p> </p>
      <p><br>
      </p>
      <blockquote type="cite"
        cite="mid:64985afa-1d8b-cc6c-3283-4fd4ef0f5d1a@oracle.com"> <br>
        <blockquote type="cite">If we remove access control, third
          parties will be able to open local network connections and
          freely and use Java Serialization over unsecured connections,
          exposing us to an attacker who can use a gadget attack.
          Presently they cannot open a network connection, access files
          or do much of anything without Permission.  All those
          protections will be removed with this JEP. <br>
          <br>
          from <a class="moz-txt-link-freetext"
href="https://community.letsencrypt.org/t/do-you-support-code-signing/370"
            moz-do-not-send="true">https://community.letsencrypt.org/t/do-you-support-code-signing/370</a>
          <br>
          <br>
          <blockquote type="cite">Code-signing certificates as they’re
            used today are part of systems that try to decide whether a
            software source is malicious or legitimate. I don’t think
            Let’s Encrypt could easily play that kind of role when
            issuing certificates free of charge with an automated
            process without checking the real-world identity of the
            applicant. We could confirm that a code signing certificate
            applicant controls a domain name like iurewnrjewknkjqoiw.biz
            408 <a class="moz-txt-link-rfc2396E"
              href="http://iurewnrjewknkjqoiw.biz"
              moz-do-not-send="true"><http://iurewnrjewknkjqoiw.biz></a>,
            but that doesn’t give users or operating system developers
            much ability to know whether software that that applicant
            publishes is trustworthy or malicious. <br>
          </blockquote>
          <br>
          The JVM is one of very few platforms that has sufficient
          capability to allow us to do this. <br>
          <br>
          If I could chose my pain, I would chose to remove Java
          Serialization first, before SecurityManager because while I
          understand the maintenance burden needs to be reduced for the
          ongoing viability of the Java platform, security is still of
          utmost importance, as the vulnerabilities of Java
          Serialization killed of client development. <br>
        </blockquote>
        <br>
        I don't think it is appropriate to block deprecation of the
        Security Manager until serialization is removed. Note that we
        have added mechanisms such as Serialization Filters [1] to help
        applications secure their serialization dependencies and that do
        not require a Security Manager to be enabled. We also are
        continuing to look at other improvements in this area, as well
        as introducing new features such as Records that can be
        serialized more securely [2]. <br>
      </blockquote>
      <p>I'm not suggesting blocking deprecation of SecurityManager, I'm
        requesting blocking removal of SecurityManager until after
        Serialization has been removed.   So deprecate SecurityManager,
        just don't mark it for removal yet.  Please mark SecurityManager
        for removal after Serialization has been removed.   What follows
        is the reasoning for my request.<br>
      </p>
      <p>We currently use SecurityManager and policy to prevent
        un-trusted connections which could otherwise use serialization
        or access sensitive data. Â Â  We only allow a limited subset
        re-implementation of serialization over trusted connections and
        permission must be granted before it can be used.  No trust
        established (TLS), then no Serialization.  Because we load code
        dynamically, we will not be able to profile it in advance, so we
        cannot create serialization whitelists because we have no way of
        knowing class names in advance, our only choice will be to
        disable Serialization entirely.   At least with security policy,
        we can establish the permissions in advance.<br>
      </p>
      <p>Presently the dynamically loaded code, contains a list of
        requested Permissions in META-INF, however they may not be
        granted, the security policy has a list of Permission's that are
        allowed to be granted based on the remote principal, the
        permissions granted will be the intersection of these two lists,
        requested and allowed permissions.  We can log permissions that
        are not granted.  This occurs dynamically at runtime.  A
        Permission requested may also be a subset of the Permissions
        allowed, because of implies checks.  So dynamically loaded code
        really does operate under least privilege principles.  You can't
        do that with Serialization filtering.<br>
      </p>
      <p>Prior to the introduction of the Serialization's filtering
        mechanism, I re-implemented a subset of Java Serialization,
        focused on addressing vulnerabilities caused by gadget attacks.</p>
      <p>We did this when other companies solutions to addressing Java
        vulnerabilities was to remove Java altogether, which is why Java
        applets are no longer used.  Instead, we knuckled down and
        addressed the vulnerabilities.<br>
      </p>
      <p> I had to remove circular links because they introduce security
        vulnerabilities, I also limited the number of bytes the stream
        can download before it must be reset, otherwise an IOException
        is thrown and control is returned to the caller.  It uses
        constructors, and all classes are expected to validate
        invariants.  We've discussed it previously.  Apart from
        Collection classes, serial form of existing classes has not been
        altered, instead classes have new Constructor's that are used to
        validate their de-serialized fields.  All fields have also
        undergone their own validation process.  J.B. called it atomic
        serialization, when we first discussed it, so that's what we
        call it.</p>
      <p>My first step was to re-implement deserialization and use that
        for some time with the new deserialization public API,  I'm
        currently implementing a public API for serialization.  After
        this I will introduce more serialization protocols that use the
        same API, at that time I may have to change the serial form of
        some classes, as Java serialization had a lot of complex
        features that other serialization protocols lack.  The
        deserialization api, is capable of supporting multiple serial
        forms, to allow class implementations to change them.<br>
      </p>
      <p>Certain Java Collection classes are vulnerable to denial of
        service attacks, so they are not serialized, instead I have
        serializers that transfer the data, which is validated during
        deserialization, before populating the Java Collection classes
        via constructors.  This means any Collection class can be
        serialized, even those that don't implement Serializable, they
        all have the same serial form, so their serialized form
        basically respects the Collection interfaces of Map, Set and
        List, their bytes can be compared for equality, for example if
        two Map's are equal, their serialized bytes will also be equal.<br>
      </p>
      <p>Furthermore serialization filters have the same complexity
        flaws as the Security Manager model, but in our case we use
        SecurityManager to grant a limited set of privileges that we are
        able to establish prior to loading dynamic code.    We already
        have a profiling tool that generates policy files.</p>
      <p>Once SecurityManager is removed, third party code will have all
        permission's granted to the JVM, so they will be able to view
        files and make network connections.   The serialization filters
        offer a similar level of complexity, but with less protection
        and less time for tool development.  No doubt this will require
        us to rethink the structure of our software and access control
        to sensitive data.<br>
      </p>
      <p>Once we fixed Policy performance issues and created profiling
        tools for initial creation of policy files, which are used as a
        guide to create the requested permission lists and enable
        permissions to be granted dynamically at runtime, security
        becomes a significant benefit rather than a burden.</p>
      <p>To quote waratek: reference <a class="moz-txt-link-freetext"
          href="https://www.waratek.com/java-serialization-filtering/"
          moz-do-not-send="true">https://www.waratek.com/java-serialization-filtering/</a></p>
      <p> </p>
      <blockquote type="cite">
        <p>To configure Serialization Filtering, the application needs
          to first be fully profiled. <strong>Profiling</strong> an app
          can be a complex process that requires specialized tools and
          has to be performed by domain experts. Typically, the process
          requires the app to run normally for a period of time in order
          for all its paths to be executed. A dynamic profiling tool can
          log the class names that are required for normal operation.
          This list of class names will then be the basis of configuring
          the white/black list of the Serialization Filters. And even
          after going through this process, there is no guarantee that
          all of the execution paths were run and all the required class
          names were logged. Of course, the same process needs to be
          performed every time a new release goes into production or
          even when a third-party library must be upgraded. The
          lifecycle of this process becomes even more complex since such
          any change in the Serialization Filters will first need to go
          through QA and UAT before it reaches production.</p>
        <p>The Serialization Filtering mechanism follows a very similar
          approach to the <a
href="https://docs.oracle.com/javase/7/docs/api/java/lang/SecurityManager.html"
            target="_blank" rel="nofollow noopener"
            moz-do-not-send="true">Security Manager</a>. The Security
          Manager also works based on a <a
            href="https://docs.oracle.com/javase/tutorial/security/tour2/step3.html"
            target="_blank" rel="nofollow noopener"
            moz-do-not-send="true">whitelist</a> and suffers from the
          same scalability problems. Java’s Security Manager has proved
          to be unsuitable for enterprise, large-scale environments,
          given that <strong>it moves the responsibility of protecting
            the system to the user</strong>. The user is responsible for
          understanding the application’s security requirements and
          technical details and correctly configuring the security
          policy, which in essence is a whitelist of permissions. Such
          security policies are typically very complicated in enterprise
          applications that change frequently and integrate with
          numerous different systems and components. The <strong>operational
            cost</strong> of correctly configuring and maintaining such
          security policies is so high that Security Manager is rarely
          deployed in production environments [<a
            href="http://www.hpl.hp.com/techreports/98/HPL-98-79.pdf"
            target="_blank" rel="nofollow noopener"
            moz-do-not-send="true">6</a>] [<a
            href="http://tomcat.apache.org/tomcat-7.0-doc/security-howto.html"
            target="_blank" rel="nofollow noopener"
            moz-do-not-send="true">7</a>].</p>
      </blockquote>
      <br>
      <p>I would elaborate that the above problems with SecurityManager
        have been address in practice, as we've had many years to
        address them, these solutions are not included with Java of
        course.  The responsibility is not with the user, but developers
        and administrators.<br>
      </p>
      <p>Also it has become apparent to me, that Java is following in
        the footsteps of Unix.   First workstations were replaced by
        cheaper PC's, so the workstation market was lost, then the PC
        version of Unix, Linux ate Unix's lunch in the Server market. 
        Java no longer has a client market, no longer on phones or the
        browser, some desktop deployments, it has largely retreated to
        servers.  Be careful not to diminish Java's market too much,
        lest Android eat Java's server market lunch.  Android has a
        newer fine grained security model, I don't know if it can be
        applied to a server environment.   I don't mean to be
        inflammatory, just giving you ammunition, should you require it.<br>
      </p>
      <pre class="moz-signature" cols="72">-- 
Regards,
 
Peter Firmstone
Zeus Project Services Pty Ltd.</pre>
      <p><br>
      </p>
      <blockquote type="cite"
        cite="mid:64985afa-1d8b-cc6c-3283-4fd4ef0f5d1a@oracle.com"> <br>
        --Sean <br>
        <br>
        [1]
        <a class="moz-txt-link-freetext"
href="https://docs.oracle.com/en/java/javase/16/core/serialization-filtering1.html#GUID-3ECB288D-E5BD-4412-892F-E9BB11D4C98A"
          moz-do-not-send="true">https://docs.oracle.com/en/java/javase/16/core/serialization-filtering1.html#GUID-3ECB288D-E5BD-4412-892F-E9BB11D4C98A</a><br>
        [2] <a class="moz-txt-link-freetext"
          href="https://inside.java/2021/04/06/record-serialization-in-practise/"
          moz-do-not-send="true">https://inside.java/2021/04/06/record-serialization-in-practise/</a>
        <br>
      </blockquote>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
Regards,
 
Peter Firmstone
0498 286 363
Zeus Project Services Pty Ltd.</pre>
  </body>
</html>