Hi Ron,

So far we have dealt with CORBA (external library), pack200 (working on an external lib) and to support Java 17, removed some Activation class dependencies (we don't use RMID, so grabbed the missing Activation classes from Apache Harmony), thankfully these were not challenging, although replacement of some Activation classes will require downstream developers to edit their imports and recompile their code, some are still stuck on Jini 2.1 api compatibility, I have a Jini 2.1 compatibility layer, that allows them to use JGDMS without re-compiling, they will be impacted by the changes.  There are a number of projects that use the Jini 2.1 api still.

We have a number of our own permission implementations of course, such as DeSerialzationPermission and one that's misnamed called DownloadPermission, which should have been called "ClassLoadingPermission", because it doesn't prevent code downloads, URLPermission does that.

These are actually external defenses, and are best granted to authenticated services (dynamically granted incrementally following successful authentication), these are gates in the process of loading a service proxy.

We only let the good guys through the door, but we still have a gun safe to stop the kids from accidentally shooting each other.

So we've figured out that we can recreate most of the authentication layer, the challenges will be implementing Java platform level guards.

That's why we still need authorization controls on things like ClassLoading, network, filesystems and properties, once we allow the service proxy to load code.  It appears unlikely that OpenJDK will provide hooks here, so we need to wait for finalizers to be removed, so we can instrument constructors (we don't want to inadvertently open any holes to the outside by making ClassLoader sensitive to finalizer attacks).

Perhaps with ClassLoader, we should instead guard the actual methods that load classes instead of the constructor, it's not practical to do that with network connections however as it would take a big performance hit, same with filesystems.   Our reimplementation of URLClassLoader is much faster because it doesn't make unnecessary DNS calls, so a small impact with guards, we may still be faster anyway.

The policy tool currently used for auditing to establish trust will need to be replaced by new tools that OpenJDK is providing in future.   Clearly auditing needs to increase to offset missing permission checks.  Once we do that, then we can use SHA hashes to identify codebases and allow their classes to be loaded.

It's still a moving target, with potentially significant implications if we get it wrong.

Whether we continue developing in Java will depend on a number of factors:

1. How successful we are at navigating JEP 411.
2. Other future JEP disruptors (assuming we succeed with JEP 411).
3. Overall cost of development and maintenance in Java, v's another
   language.
4. Cost / benefit of using another language.
5. API stability of other languages.
6. Longevity of other languages v's Java.

I'm working on the assumption that OpenJDK will close any external holes currently defended by permission checks.  It would be good if the JDK was secure by default, with properties required to be set for allowing such things as agents, management, parsing xml and serialization.

We still need some authorization layer controls for trusted users and services, and balance it with increased auditing of code. It's not possible with static analysis to determine the intended use of reflection, so we'll need new observability tools to replace the current policy tools.   Perhaps we can link the observability tools to a service watchdog, if a service proxy misbehaves, then, it gets blacklisted and the affected JVM is immediately restarted.

Our code is dynamic, so we might need to create an audit service that provides a list of audited proxy codebases and their SHA-256 hashes.

Keep in mind this is all completely experimental and subject to change.

Regards,

Peter.

On 31/07/2021 6:22 pm, Ron Pressler wrote:
Hi Peter.


- JEP 411, like every spec-changing JEP, is meant to allow those that use the 
removed functionality
a migration path forward. The API elements that are deprecated for removal have 
some years before
they are actually removed, so there’s nothing too urgent other than beginning 
to think of a migration
path. I think it’s still too soon to consider concrete suggestions for change, 
especially non-trivial
ones.

- If by Java 8 EOL you mean the time when the last vendor offers extended 
support for it, then
2030 is, I believe, the *earliest* possible date that is guaranteed *now. It’s 
possible that support
would be extended until 2130. Such offerings have no bearing on the development 
of current JDK
versions.

- The number of significant code changes required since JDK 8 to keep up with 
current JDK releases is,
for the vast majority of Java users, low (what’s affected most users is 
reliance on non-spec-compliant
libraries, and the need to import the external artefacts for EE). The most 
impactful change has probably
been the removal of some client deployment technologies from the Oracle JDK, 
but as far as OpenJDK is
concerned, the affected areas have been CORBA, pack200, Nashorn, and now the 
process to remove SM is
starting. The number of people using any one of these is low, and the number of 
those who need to work
hard for alternatives is very low. I think that advance warning, and then 
support offerings by multiple
vendors for those who have not managed to migrate in the advance warning period 
is reasonable; always
offering ways to support removed technologies together with new features in 
current releases with the
same code base is not. When compared with other ecosystems, Java’s strategy is 
exceptionally tolerant
of those that prefer slow change.

- Property-based testing is wonderful, I wish more people would use it, and I 
hope to see it used in
the JDK as well. Java has several PBT tools, but I believe the most popular one 
these days is
https://jqwik.net/. As long as you’re still with Java, give it a try.

— Ron

On 31 Jul 2021, at 04:04, Peter Firmstone<peter.firmst...@zeus.net.au>  wrote:

The current JEP 411 plan of action, if left unchanged, will leave developers 
who adopted the SM architecture as an authorization layer unable to upgrade to 
later versions of Java, until finalizers and the finalizer attack defensive 
methods in constructors are removed.  JEP 411 has the potential to cause 
significant disruption for a small proportion of Java developers, but doesn't 
have to if managed appropriately.

The blocker is the ability to implement guard checks using Agents on public 
API, due to finalizer attack defensive private static methods in constructors.

Allan has advised when finalizers are removed, it will be practical to use 
Agents to instrument public API to implement an authorization layer, this is 
try, so can it be coordinated with JEP 411 et al?

Furthermore, as developers must support multiple Java releases, I propose the 
following amendments, to ease difficulties of multiple release support (with 
multi release jars):

* AccessController, AccessControlContext, DomainCombiner and related
   Subject and Executors methods, remain until Java 8 is EOL in 2030.
   Also consider un-deprecation of these methods, as their removal
   causes shotgun surgery (used in 1000's of locations in my software
   alone) and they are required for preservation of Subject, used for
   obtaining TLS and Kerberos connection credentials on all existing
   versions of Java.
* AccessControlContext - remove inherited thread context, replace it
   with an unprivileged ProtectionDomain, such that doPrivileged
   methods are required for authorization checks and only the current
   thread stack needs to be walked when checks occur, and stack walks
   aren't unnecessarily performed when creating new threads.   This is
   compatible with Loom, update loom to allow the use of
   AccessControlContext to be used, to establish TLS and Kerberos
   connections.  Loom will be very useful for network connections,
   especially long latency connections over the internet, which are
   typically secured using TLS.   This removes the problem of viral
   checks, and Executor task privilege escalation.
* Modules that are mapped to the boot loader should get a unique PD
   that includes a useful code source rather than using a "shared" PD,
   this allows us to reduce the privileged footprint of the Java
   platform libraries, to allow privileges to be granted to users, not
   code, or users and code.  This is useful to limit data parsing
   privileges to authenticated users on servers (a practise that should
   be more widely encouraged).
* Remove finalizers, and defensive methods in constructors where
   permissions check points occur as these cause problems for Agents,
   prior to removal of SecurityManager.
* Deprecate for removal Permission implementations, then remove them
   in a following release.
* Remove SecurityManager.

This allows a forward migration path for poor sod's like myself who are 
currently using SM infrastructure as an authorization layer, and to establish 
TLS conenctions, this or at least some sort of compromise is far preferable to 
the thermonuclear option currently planned.

What I would like OpenJDK to consider, is to allow developers like myself to 
continue to stay current with Java, by coordinating the removal of finalizers 
and defensive methods in constructors, with JEP 411, so we have a workable 
future migration path. Without these considerations, options are; go back to 
Java 8, and plan to redevelop existing software, if forced to do so, Java is 
unlikely to be on the list for redevelopment, simply because development costs 
are lower in newer languages, such as automated unit 
tests,https://hackage.haskell.org/package/QuickCheck, no need to worry about 
null pointers and less boilerplate.

Don't get me wrong, I like Java and have many years experience with it, but I 
have to be pragmatic, it won't just be me, many other developers, when Java 8 
is EOL, will work for companies stuck on that platform, simply due to the 
number of changes required, because they haven't kept up (eg budgets) with the 
current release cadence and pace of development, will be looking at 
redevelopment and replacement instead of migration.   Clearly the current pace 
of development is a good thing for Java, but the overall strategy could be 
tweaked a little, to ensure migration doesn't become insurmountable.  A healthy 
and vibrant Java community is essential for the survival of Java, Java has 
already shed phone and client markets, lets not shed too many more.

Thanks,

Peter

--
Regards,
Peter Firmstone
0498 286 363
Zeus Project Services Pty Ltd.

Reply via email to