Hmm, whitelisting, you're using the principle of least privilege too then.

We have multiple SecurityManager and Policy implementations.

Our policy implementations can decorate each other with different functionality, including dynamic permissions and permissions granted by a permission service remotely, they have an interface to bubble up immutable data, so they can share immutable state.

The implementation code that ships with Java is like a model T Ford, ours is Formula 1, concurrent and non blocking, it's also very performant, we use bit shift operations, for string normalization, we've got RFC 3986 URI normalization and RFC 5982 IPv6 normalization , Java's implementation code makes network calls to DNS.  There just is no comparison there at all.  We use a comparator to order the permissions into their most performant order and it doesn't call equals or hashcode as that can cause a DNS call.

I believe we do achieve it's theoretical utility and I don't know that I would call it absolutely amazing, but it gets out of the way and just does what's is supposed to reliably, without impacting performance.  But now OpenJDK wants to rip the rug out from underneath us, because it's causing problems with loom or some other projects.  Could you just make the AccessControlContext immutable for loom threads?   We might say, ok I need a few minimal permissions for this AccessControlContext, give it one ProtectionDomain with a Subject and static Permissions, so it doesn't consult the policy, that AccessControlContext is immutable.  Get rid of the locks in PermissionCollection and make them immutable with a builder.   We create PermissionCollection on demand and discard their reference for the garbage collection, we don't actually share PermissionCollection instances.

I think also that many more people are using SecurityManager than OpenJDK realises, and they're not using it how OpenJDK recommends either, (AllPermission granted to trusted code, and sandbox untrusted code model of Applets is not how we use it) people are using POLP, it's just that no one reports back to OpenJDK because they are only editing policy files, it will work with any library out there now, there's nothing to write back about.  It's pretty clear that OpenJDK devs don't use it, but they do have to manage doPrivileged and preserving context across tasks and threads.

And there are static analysis tools in Spotbugs to identify doPrivileged bugs, but someone has recently suggested removing them thanks to this JEP?  Does OpenJDK use static analysis.  I think if you did you'd find plenty of latent bugs.

The Java implementations do impact performance, although I believe this has improved with the module system, which uses a URN instead of a URL for codesources, I haven't looked at the jrt URL handler impl.

Regards,

Peter.

On 31/05/2021 4:21 pm, Harshad RJ wrote:
In reply to Ron Pressier:
Do you regularly use the Security Manager to sandbox your own dependencies and 
find it convenient and effective
— in which case, could you please describe your practice concretely so that it 
would be possible to consider
alternatives — or are you saying that you can *envision* such a powerful 
use-case? The desire to remove the
Security Manager does not stem from its theoretical utility, which is 
absolutely amazing, but from its practical
utility, which years of experience have found to be less than amazing after 
all, and probably too low to justify
its burdensome cost.
# Practical example of SecurityManager use
We are developing a security and privacy conscious browser in pure Java:
https://gngr.info

`gngr` uses `SecurityManager` at its core to not only sandbox external
libraries but also *internal modules*!

# External Libraries we use
* `Rhino` for Javascript
* `jStyleParser` for CSS parsing and analysing
* `okhttp` for HTTP/2 support (before the Java11 HTTP client was available)

These are huge libraries that are practically impossible to audit by a
small team, but through the SecurityManager we
were able to identify the following issues very easily:

## Security issues discovered so far
* Network access by the CSS parser library:
https://github.com/radkovo/jStyleParser/issues/14

* Use of reflection to make a private method accessible
https://github.com/square/okhttp/issues/3426

# Trust, but verify
We don't use `SecurityManager` because we don't trust the external
library authors; we do trust them else we wouldn't
be using those libraries! And given that these are popular projects,
we can also bank on oversight from the community
at large.

But what if we could also verify this trust and other assumptions, for
very little overhead? The SecurityManager does
require initial time investment, but IMO the returns justify it.

A good example of trust but verify, is our own internal modules. We
obviously trust our own code, yet we sandbox it,
to be sure that our assumptions are correct. For example, the `Cookie`
module inside the browser only needs File
access, in order to persist the cookies. Having it sandboxed relieves
us from worrying about some bug or debug code
mistakenly accessing the internet or any of the other myriad
capabilities that the code has access to.

# Numbers are misleading
One argument I have seen in support of JEP 411 is that there are very
few projects that use the SecurityManager. But
this outcome seems natural to me:
1. Many users and developers are not aware of Security threats, or
don't give enough priority to them.
2. The SecurityManager is hard to setup.

I expect #1 to change over a period of time, as more data gets
breached and more people learn from this experience.

#2 could be solved with better documentation, tutorials, etc. Or
through development of an alternative API.

(Imagine if WeakReferences were removed from the JVM because they were
not used by many projects! Of course, they won't
be used by many projects because they are not relevant to most of
them. However, for the projects that do use them, they
are very essential.)

# Logging events violates POLP
The alternative of using logging, with JFR for example, might be
suitable for certain use-cases, but is not a general
replacement for the protections provided by SecurityManager.

For one, it might not be possible to exercise all code-paths in tests.
Hence, the events made during testing might be
a subset of the actual behavior in production.

Secondly, it is not possible to know all events that need to be
captured in advance. Using a SecurityManager allows
us to follow a whitelisting policy, which is practical because the
white list is finite.

However, the alternative of logging events requires us to list all
possible capabilities in advance, which is impossible,
as the capabilities provided by the JVM or the standard library might
grow in a future version.

Thirdly, using Java agents with bytecode manipulation, as suggested on
this list, doesn't seem any easier than using
the SecurityManager.

best,

Reply via email to