<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>