<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <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>
    <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">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"><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/">https://www.waratek.com/java-serialization-filtering/</a></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">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">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">6</a>] [<a
            href="http://tomcat.apache.org/tomcat-7.0-doc/security-howto.html"
            target="_blank" rel="nofollow noopener">7</a>].</p>
      </blockquote>
      <br>
    </p>
    <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">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/">https://inside.java/2021/04/06/record-serialization-in-practise/</a>
      <br>
    </blockquote>
    <pre class="moz-signature" cols="72">
</pre>
  </body>
</html>