[External] : Re: JEP411: Missing use-case: Monitoring / restricting libraries
ron.pressler at oracle.com
Wed May 5 13:12:16 UTC 2021
> On 5 May 2021, at 05:04, Peter Firmstone <peter.firmstone at zeus.net.au> wrote:
> 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.
Any API has a non-zero risk of removal after decades of use, and that risk is commensurate with its level of use. I think
this is always true, and that everyone already knows that and finds that acceptable, because it’s better than any other
alternative. In this particular case, we’re discussing the removal of an API after three decades of use, with under 0.1%
of codebases making use of it.
> Got any example best-secured systems?
I would hope that Apple's, Amazon’s, Google’s and my bank’s systems, many of which are Java, are secure.
> 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.
The whole design of the security manager as a “path-dependent” deep sandbox is built around untrusted code, hence
all the stack-walking and doPrivileged. Trusted code means assumed not to be malicious. As such, what you want to protect
against is vulnerabilities. Since you don’t know where they are, you place the entire application in a sandbox that’s
both more airtight and less complex than the Security Manager. That is, in fact, how most people do it.
> 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?
We are not talking about authorisation or access control. We’re talking about the Security Manager’s design and implementation
which is about code domains and stack-dependence. Serialisation’s security is one thing and the Security Manager is a whole other
> 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.
You are conflating the Security Manager with security. A lot of security work has been going on in the JDK for the past few years
(and will continue for as long Java exists), but not in the code-protection-domain-sandbox known as the Security Manager.
More information about the jdk-dev