-bcc jdk-dev
-cc security-dev
On 5/5/21 12:04 AM, Peter Firmstone wrote:
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.
But you use self-signed certificates to sign the code that will be run.
There is no trust in self-signed certificates unless you have previously
used some out-of-band mechanism to trust the public key. I still don't
understand why this is not the same as running untrusted code, even if
the code is sandboxed. And trusting the TLS server is not an equivalent
basis of trust.
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.
There is a plan for preserving the capability to transfer Subjects to
other threads. It is described in the JEP:
https://openjdk.java.net/jeps/411#Alternate-JAAS-APIs
--Sean
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.