A VALUABLE LESSON FOR ANY JAVA DEVELOPER: DON'T PUBLISH ANY java.*
package namespace API'S THAT MAY BE AT RISK OF LATER REMOVAL IN YOUR
API, java.* API's ONCE REMOVED CANNOT BE REPLACED. IF YOU ARE
CONCERNED SOMETHING MAY BE REMOVED IN FUTURE, SUBCLASS IT IN YOUR API,
OR CREATE AN INTERFACE WITH SUBCLASS DECORATOR, SO THAT YOU HAVE SOME
CONTROL OVER BACKWARD COMPATIBLE API EVOLUTION.
On 5/05/2021 10:08 am, Ron Pressler wrote:
Resent with plain-text formatting (I hope) & corrections/rephrasing
On 4 May 2021, at 03:49, Peter Firmstone <peter.firmst...@zeus.net.au> wrote:
Yes, I'm sure millions of developers don't use the security infrastructure
because they only have low value data to protect, or it belongs to someone else
and developers that do, can use it incorrectly, it's probably worse to do the
latter, but then people synchronize incorrectly too, but we don't remove
synchronization because of that.
The Security Manager hasn’t been a central part of Java’s server-side security
for years. Some of the most critical and
best-secured systems in the world are written in Java, and they don’t use the
Security Manager, so let’s not equate a
particular sandboxing mechanism designed for untrusted code with security.
Got any example best-secured systems?
I think we are talking past each other here. You keep talking about
untrusted code, which sounds like applets to me. I've read and still
have a copy of Li Gong's book, applets were only one of the
considerations. I am talking about authorization and access control.
We use and develop distributed or p2p systems, we don't allow untrusted
code to run at all, never ever, that's a dumb idea, so lets stop talking
about untrusted code, we don't use that. We do utilize dynamic
downloaded code from others and use dynamic class loading, we verify
this prior to loading. We check it's authorized to run before running
it. Again I repeat, we do not run untrusted code, that would allow an
attacker to cause denial of service etc, the JVM has no control over
badly behaving code.
We've been using this since Java 1.4, to control access to networks,
file systems and other custom permissions we created, it is used to
protect access to sensitive data. We are still using it. I understand
access control will be removed:
https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-spec.doc4.html#20389
We would like to continue restricting access to data after the above is
removed. Will Java be introducing new Role Based Access Control API or
something similar?
Our software will fail to run on Java after the above is removed. I
understand we have to remove access control functionality from our
software for it to continue functioning? We do need to understand how
this will impact security, I think you are trying to convince me or
yourself that security will not be impacted? We can't just assume we
can remove access control and our software will be no less secure.
What is the new API for access control in Java?
Obviously we won't have a call stack with domains, I don't know how we
will transfer the user Subject to other threads, for TLS and Kerberos
connections. No doubt something is planned.
Is the recommendation simply not to upgrade Java until new access
control API is developed?
<SNIP>
Please provide some examples, migration options suggestions will be
appreciated.
I’ve jotted down some thoughts in a blog post:
https://inside.java/2021/04/23/security-and-sandboxing-post-securitymanager/
Noted, a good start. I get the feeling this JEP is being rushed through
however, with little regard for those of us who were foolish enough to
use Java's security API's and will have to suffer the consequences.
With Serialization, we've been given more than ample notice to do something
about migrating away from it, but OpenJDK paints over it and wastes resources
adding features to putty and paint over it some more, features that no one
uses. Removing Serialization has greater appeal :)
This step to remove SecurityManager is so sudden with no replacement options,
it's a broken promise to developers, who've invested in Java.
Removing SecurityManager has a significantly negative effect on security for
me, just so you know. I'm not happy about its proposed removal, but I realise
there's not much I can do about it, other than request it be done in the least
painful manner.
I began learning Java over 20 years ago, I understand the need to keep Java
relevant, however move quickly and break things is for younger software
platforms.
Not everyone has to agree with every priority decision, and the process doesn’t
require convincing every last Java developer. But
it is not sudden, and there will be alternatives for those aspects of Security
Manager that more people use. I don’t think it is fair
to harm millions of Java developers by diverting resources from features they
want to features very few people want, as long as
a reasonable removal process is employed, and I think it is here.
Once SecurityManager has been removed, we will lose control over who has access
to sensitive data, so it's likely we will be stuck on the last version of Java
that provides SecurityManager. The best way I can see for those who need the
level of security that SecurityManager provides is to maintain a community LTS
edition on OpenJDK, it will be much easier to maintain and backport security
patches if Serialization in its current form has been removed, as it will
likely have been removed from later versions of Java by that time.
I disagree. I don’t think that the Security Manager offers a higher level of
security, just a very elaborate and fine-grained one.
Right now I can limit network access using a permission, or I can
prevent file access, database access, or even access to objects
themselves. This is for generally well behaved party's, but we still
have to have controls in place.
https://www.acsac.org/2009/program/keynotes/gong.pdf
Regarding a higher level of security:
Q1. What does an attacker who is using serialization as an attack vector
want to gain?
A1. Property: intellectual, fiat currency, identity theft etc.
Q2. Why does an attacker use Serialization as the attack vector?
A2. Because it allows an attacker to create any object they like in the
JVM, even inject code, the attacker first attempts privilege
escalation. Java makes this easy, because the implementation doesn't
place an unprivileged ProtectionDomain onto the call stack. A simple
initial fix would have been to modify the AccessControlContext to
include an unprivileged ProtectionDomain on the call stack when a user
creates an instance of ObjectInputStream. Granted there were still
cases of JVM classes that deserialized into a doPrivileged call that
needed to be addressed.
Q3. SecurityManager and policy providers use whitlists. The complaint
about SecurityManager is that whitelisting is too complex. Why
entertain a new white listing api for Java Serialization, when
complexity is the argument for removing SecurityManager, but it's even
worse than SecurityManager, at least with the policy whitelist you have
some forward knowledge.
A3. Any ideas?
Lets be clear Java will no longer be able to finely control access to sensitive
data with the removal of SecurityManager. I'm sure it will be a great bonus
for OpenJDK dev's not to have to think about, but it will impact some
developers significantly, who would like to do so with the least suffering
possible.
I wouldn’t say Java (or anything else, for that matter) is “able" to do it now,
except in the sense that people (scientists) are
able (in a billion-dollar particle accelerator) to transmute lead into gold (a
few atoms). We’ve had twenty five years to convince the world this could work,
the world isn’t buying, and our job isn’t to sell ideas but to serve millions
of developers by giving them
what we believe they need now, not what we wished they wanted.
— Ron
Of course Java is "able" to do access control, it's well documented, I
have working examples. No security defense is 100% effective, if you
look at the history of defenses, they continue to evolve. Just because
ObjectInputStream was a huge security hole, it didn't inject an
unprivileged ProtectionDomain onto the stack, which would have stopped a
number of deserialization gadgets. ObjectInputStream runs as
privileged code, tut, tut, tut! Perl taint mode anyone?
Java 6 introduced a security feature where an object will not be
constructed if Object's constructor is not called, so that invariants
must be satisfied before object creation. Java Serialziation bypasses
this. Prior to Java 6, objects could be left in a partially constructed
state and obtained via a finalizer attack.
Besides, serialization whitelists don't protect against denial of
service, so why have them at all if you using trusted systems and TLS
connections? Java Serialization should never be used to process
untrusted data, because it doesn't and cannot validate invariants until
after objects are constructed which is too late. As soon as you
implement Serializable, all the effort you put into defensively coding
constructors can be bypassed. So why code defensively at all if we
leave a back door wide open anyway? All code is trusted now right, soon
we can make sure all connections are secure, so we don't need to worry
about input validation anymore either right, because the users are
trusted now too? Maybe we should just whitelist the classes allowed to
run on the JVM and not worry about coding defensively? Sounds silly,
well that's how it sounds to me, just thought I'd put it into perspective.
Java Serialization still compromises the security of the JVM because it
doesn't prevent object creation if invariants aren't satisfied, the
vulnerability is still there, and future attackers will find a way take
advantage of it for that reason.
It is clear that no further progress will be made in this matter and I
will simply have to live with the consequences. Stick a fork in me,
because I'm done.
--
Regards,
Peter Firmstone
Zeus Project Services Pty Ltd.