PrivilegedAction et al and JEP411
Peter Firmstone
peter.firmstone at zeus.net.au
Mon Jun 19 22:44:55 UTC 2023
It looks like you got their attention. :)
Although we've had the assurance from OpenJDK that we could implement an
authorization framework using StackWalker and agents, I've found it's
not feasible, since privileged actions will be lost and there will be no
support from OpenJDK, it would destroy the principle of least privilege
that we currently have; permissions would have to be granted to all
domains on the call stack, privileged actions currently allow those
permissions to be limited, but clearly there is no way we can add this
functionality back after its removal. Defending a privilege is waste of
time if it has to be granted to everyone anyway.
In recent years, we've been seeing more and more permissions required by
JDK implementation code, leaking out, such as the following, our code
doesn't import any of these packages, but we have to grant permission to
our code, because JDK implementation code isn't using privileged actions
to access them, removal of privileged actions from the platform would
cause an exponential explosion in the number of permissions required.
permission java.lang.RuntimePermission
"accessClassInPackage.sun.reflect";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.action";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.ec";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.rsa";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.jca";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.krb5";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.pkcs";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.provider";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.util";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.util.math";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.util.math.intpoly";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.x509";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.util.locale.provider";
One of the lessons that have come from the discussions of JEP411, is we
can use agents to insert permission checks, where there are none
currently, so we'll be able to further lock down the JVM, than is
currently possible, this will allow us to make decisions on data
parsing, such as the trust relationship with the entity that provided
the data, it also means we can forget about the complexity of
serialization filters, by not allowing deserialization of data from
outside the JVM and limiting its use within, the best option is to
disable Java serialization completely of course, but then Java Flight
recorder, and other visibility tooling use RMI and Java Serialization.
One of the things I would have liked to do, would be to reduce the size
of the trusted platform, by restricting permissions for parts of OpenJDK
itself, this would only be possible if we rolled our own JDK, maybe
we'll do that one day, but we can't call it Java ;)
We try to support multiple versions of Java, from Java 8, up to the most
recent version, the only way to stay compatible will all versions is to
use deprecated API, hopefully OpenJDK will backport some of their new
API for developers who don't use SM.
Even we have small utility command line programs, where we don't use or
require authorization, where SM doesn't need to be enabled.
OpenJDK dev's have worked hard to improve encapsulation, however OpenJDK
has made it abundantly clear, that even if the community could maintain
and improve a feature, corporate has the final say and will do whatever
they want anyway, as much as I appreciate the hard work of OpenJDK
developers, corporate has the last say. We saw this previously with
JPMS v's OSGi, JPMS has no versioning capability, OSGi's service model
is superior to ServiceLoader, while everyone agrees JPMS is good for the
Java platform's encapsulation, my personal preference is OSGi for its
superior long term maintenance of application code, JPMS missed some of
the lessons OSGi had to offer. OSGi also has very good automated
tooling, which allows us to support it, without forcing our downstream
developers to adopt it. It isn't clear how to support both OSGi and
JPMS, it's not something we want to dictate to users, we want them to
have the freedom to choose, so we've focused on OSGi support, without
requiring users to adopt it.
It's also worth mentioning, the flaw in the argument that OpenJDK is for
server side programming now (a publish subscribe model, that only parses
data); that all code must be audited prior to deployment, the reality is
that Maven, the most commonly used build environment, pulls in a lot of
transitive dependencies that needs auditing and there needs to be more
tools to audit it, static analysis and known vulnerabilities are a good
start, but these don't capture everything, for over a decade we also use
SM for auditing, there currently aren't any tools that provide the same
level of visibility, perhaps there will be in future. But more
important than auditing alone, we can enforce what we audit. Until
something better comes along, we don't have a choice and must continue
using it.
Currently we use Spotbugs, Owasp and our own tool to determine
permissions required by software. Even if you aren't using SM in
deployed code, it's a good auditing tool and I'd recommend it's use
while it remains available, even if that means using an older JVM to
audit your code.
The tool can be found here, in case anyone is interested:
https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/tools/security-policy-debug/src/main/java/org/apache/river/tool/SecurityPolicyWriter.java
Here's are some good videos I recommend people watch, if they find Java
security interesting, be warned however, ignorance is better if you
value your sleep:
https://www.youtube.com/watch?v=uVob-4aXbxY
https://www.youtube.com/watch?v=sIuVbVbjZcw
--
Regards,
Peter
On 19/06/2023 10:28 pm, chap at anastigmatix.net wrote:
> On 2023-06-19 07:48, Peter Firmstone wrote:
>> Having an authorization layer, made it more difficult for attackers
>> to gain access to sensitive information, such as properties, especially
>> if you were using policy files with least privilege principles.
>
> Agreed. I hope it did not seem as if my recent questions/suggestions were
> directed at your efforts ... I meant them for the OpenJDK devs.
>
> It does seem that the deprecation/removal of what's being called
> "the security manager" does not signal a complete abandonment of
> all aspirations for safety in Java. There is the strong encapsulation
> in JPMS (unavailable when Li Gong's work was first done), and new
> APIs like the foreign function and memory access are being designed
> with an eye to restricting certain operations that could permit
> arbitrary behavior. The new tactic seems to be to control such
> operations by command-line options that permit the operations
> only to specific named modules.
>
> It seems that the approach being taken offers at least some
> rudiments with which secure APIs might be built, albeit with
> less configurability than the former approach (and no answer to
> the confused-deputy problem). My own interests are chiefly in
> being able to control access to operations outside the process:
> file and socket I/O, process manipulation, and the like.
>
> There seem to be some pieces of solutions to some of that.
> There is a FileSystem API that allows a default implementation
> to be specified on the command line at startup (and is passed
> a reference to the underlying implementation, so it could be
> used to mediate access). I seem to recall, though, a conversation
> indicating the JDK may still have some file accesses that don't
> use the newer API and so would not be mediated. While there is
> obviously a bootstrapping challenge--some of those accesses
> have to work early, before the FileSystem classes are ready--
> making sure that all such remaining exceptions are fixed to
> go through the new API once the early startup is complete
> could be some low-hanging fruit for the OpenJDK devs to make
> sure the platform at least offers a plausible way to control
> those operations.
>
> It likewise seems there is a SocketFactory API that could
> be used to control those IPC operations.
>
> I am not aware of any current API that could be used to
> mediate Process or ProcessHandle operations, and that might
> be another piece of low-hanging fruit.
>
> I still wonder whether it is intended, after the last
> stages of JEP 411, that all system properties will end up
> being read-write. Quite a few of them now are read-only
> sources of important platform information, and I'm not sure
> what evaluation has been made of the possibilities for
> mischief when arbitrary modification is permitted to any
> of those.
>
> Of course there is a separate 'security property' API that
> currently puts limits of its own on modification of those
> properties. Will that still exist, and will there be some
> form of control on modification?
>
> Regards,
> Chapman Flack
More information about the security-dev
mailing list