Re: JEP 411: Missing use-case: user functions in an RDBMS

2021-06-01 Thread Geertjan Wielenga
We have updated the JEP with a few changes to the "Issue Warnings"
section [1], summarized as follows:

If the Java runtime is started without setting the system property
'java.security.manager' then a custom Security Manager can be installed
dynamically by calling System::setSecurityManager, just as in Java 16.
No UnsupportedOperationException will be thrown. This call will,
however, issue a warning message explaining that the Security Manager is
deprecated and will be removed in a future release.

We plan to change the default value of the 'java.security.manager'
system property to "disallow" in the next release, i.e., Java 18. That
will cause System::setSecurityManager to throw an
UnsupportedOperationException in Java 18.

With these changes, the process of deprecating and eventually removing
the Security Manager will be consistent with our treatment of past
breaking changes such as, e.g., the strong encapsulation of internal
APIs. Maintainers of libraries and applications will be given fair
warning before any existing code is broken.

https://mail.openjdk.java.net/pipermail/jdk-dev/2021-May/005616.html



On Sat, May 29, 2021 at 12:04 AM Peter Firmstone <
peter.firmst...@zeus.net.au> wrote:

> While I accept that my particular use case will no longer be supported
> in future, it's difficult to see the value of a sandbox, because
> developers will always want to relax it in some way and people fall into
> the trap of thinking that trust is black and white; this is trusted,
> that is not.
>
> Nowadays, there's a lot more interest in the Principle of Least
> Privilege, especially in health care regulations, now I'm going to use
> the meaning implied in "Inside Java 2 Platform Security, Second
> Edition", so that we aren't arguing whether that applies with the JVM or
> external to it.
>
> The reason POLP is simpler, is that it can be automated with tooling,
> then the development / deployment team may choose to relax it, they can
> certainly test it and validate it.   Then we are simply focused on what
> we need to do, rather than what we might want to restrict, which is
> always unknown and subject to change.
>
> The problem is that this is not how developers have been taught to use
> SecurityManager, instead they are told that trusted code can be given
> AllPermission because it's trusted and that's an approach which has
> proven largely ineffective and the OpenJDK development team carry's the
> cost as a result, with little benefit.
>
> I just thought I'd provide you with a different perspective, so
> hopefully the mistake isn't repeated.
>
> Peter.
>
> On 28/05/2021 8:09 pm, Ron Pressler wrote:
> >
> > Deep sandboxes, simple or stack-dependent, are useful for very “rich”
> code,
> > that is potentially very big and possibly contains arbitrary third-party
> > libraries, while shallow sandboxes are more suitable to limited plugins.
> >
> > While a complex, stack-dependent, deep sandbox *could* be used for
> plugins,
> > permissions that don’t specify what is forbidden but what is allowed
> > effectively also severely limit the use of third-party libraries, that
> > for example, might want to do benign operations with their own files,
> > and so effectively only allow very limited plugins. The result is a
> costly
> > mechanism that is overkill for what it’s used for.
> >
> > — Ron
>
>


Re: JEP 411: Missing use-case: user functions in an RDBMS

2021-05-28 Thread Peter Firmstone
While I accept that my particular use case will no longer be supported 
in future, it's difficult to see the value of a sandbox, because 
developers will always want to relax it in some way and people fall into 
the trap of thinking that trust is black and white; this is trusted, 
that is not.


Nowadays, there's a lot more interest in the Principle of Least 
Privilege, especially in health care regulations, now I'm going to use 
the meaning implied in "Inside Java 2 Platform Security, Second 
Edition", so that we aren't arguing whether that applies with the JVM or 
external to it.


The reason POLP is simpler, is that it can be automated with tooling, 
then the development / deployment team may choose to relax it, they can 
certainly test it and validate it.   Then we are simply focused on what 
we need to do, rather than what we might want to restrict, which is 
always unknown and subject to change.


The problem is that this is not how developers have been taught to use 
SecurityManager, instead they are told that trusted code can be given 
AllPermission because it's trusted and that's an approach which has 
proven largely ineffective and the OpenJDK development team carry's the 
cost as a result, with little benefit.


I just thought I'd provide you with a different perspective, so 
hopefully the mistake isn't repeated.


Peter.

On 28/05/2021 8:09 pm, Ron Pressler wrote:


Deep sandboxes, simple or stack-dependent, are useful for very “rich” code,
that is potentially very big and possibly contains arbitrary third-party
libraries, while shallow sandboxes are more suitable to limited plugins.

While a complex, stack-dependent, deep sandbox *could* be used for plugins,
permissions that don’t specify what is forbidden but what is allowed
effectively also severely limit the use of third-party libraries, that
for example, might want to do benign operations with their own files,
and so effectively only allow very limited plugins. The result is a costly
mechanism that is overkill for what it’s used for.

— Ron




Re: JEP 411: Missing use-case: user functions in an RDBMS

2021-05-28 Thread David Lloyd
On Thu, May 27, 2021 at 8:36 PM Chapman Flack  wrote:

> Hello, I see I am another person relatively late to stumble on this
> "well publicized" JEP. (I am not sure how to recommend the publicity
> could have been better handled, but apparently the avenues that were
> used aren't ones that reached me.)
>
> I maintain, on a volunteer basis, the extension for Java server-side
> functions in the PostgreSQL RDBMS [1].
>

I posted this alternative proposal over on jdk-dev, I suppose I should
have CC'd this list as well. The idea is that maybe the SecurityManager
could stay with enough scaffolding for a third party  (say, your extension)
to be able to use their own stack-based access checker (made practical
thanks to the new-ish StackWalker API).

Anyway here it is:

-- Forwarded message -
From: David Lloyd 
Date: Sat, May 22, 2021 at 9:11 AM
Subject: Re: JEP proposed to target JDK 17: 411: Deprecate the Security
Manager for Removal
To: 
Cc: jdk-dev 



On Fri, May 21, 2021 at 6:04 PM  wrote:

> The following JEP is proposed to target JDK 17:
>
>   411: Deprecate the Security Manager for Removal
>https://openjdk.java.net/jeps/411


I'm not a committer or reviewer, so perhaps my feedback is unwelcome - but
one can't help but note the amount of heated discussion on this topic, and
the determination of whether or not the problematic points have been
addressed satisfactorily is probably pretty subjective.  I have a bit of
experience in this area, having either designed or having had a major part
of the design of the authentication and authorization APIs presently in use
in WildFly [1], as well as the WildFly security manager [2] (and a
significant number of other security-related APIs), so I thought I'd give
some feedback and also offer a possible compromise.

The security manager defines a variety of behaviors.  Some of these have
clearly been supplanted by other APIs (like getClassContext() vs
StackWalker) or security mechanisms (checkPackageAccess() and friends vs
the new encapsulation protections).  There are also however other APIs on
the security manager which clearly have no replacement.  These include
socket and file access checking APIs, and of course the general permission
check methods.  In addition, the JEP proposes deprecation of the access
controller and policy classes which are the mechanism of stack-based access
checking, and finally unavoidably bumps against JAAS, which itself is a
very difficult and problematic API which also uses the same stack-based
access mechanism (and which we here at Red Hat have for the most part long
since abandoned).

A large part of this deprecated machinery relates to the stack-based access
controller (not to mention, I believe, a nontrivial number of CVEs).  The
idea, of course, was that one can authenticate untrusted or semi-trusted
code.  It is definitely clear through years of experience on all sides
though that one cannot truly rely on this mechanism to protect against
malicious code; it is as easy as an infinite loop to cause massive
undesired CPU usage (and, in this modern $/cpu world, cost) for example.

However, one other undeniably useful function of the security manager is to
authorize basic native operations *not* in the context of what code is
executing, but what person or principal is executing it.  In other words,
the use case of *trusted* code running on behalf of one of many potentially
untrusted users - probably the widest application of server-side Java in
existence today.  It cannot be argued that removing all of the above
security checks does not weaken security of such users, when they could
have a narrower authorization applied to them to limit the possibility of
impact of server exploitation.

On the other hand, the cost of the SecurityManager mechanism as it stands
is undeniably too high; there is absolutely no point in arguing
otherwise, in my view.  Leaving aside the substantial CVE load, the access
controller and policy APIs are very difficult to use correctly by
containers and frameworks, for one thing, and are cumbersome for users as
well.  Many users and frameworks get doPrivileged() wrong, and combining
JAAS subjects into the same mechanism historically doesn't even work
consistently between otherwise-compliant JDK implementations.

What I would propose then is a compromise aimed at maximizing the amount of
value retained and minimizing the amount of cost incurred, by *only*
retaining permission checks that specifically pertain to or are useful for
user authorization, while *also* deprecating (for removal) the existing
problem-prone stack-based access checking mechanism, policy, and security
manager implementation.

Thus I would suggest not deprecating all of SecurityManager, rather just
the following:

* java.lang.SecurityManager#getClassContext - it is replaced by StackWalker
* java.lang.SecurityManager#getSecurityContext
* java.lang.SecurityManager#checkCreateClassLoader
* 

Re: JEP 411: Missing use-case: user functions in an RDBMS

2021-05-28 Thread Chapman Flack
On 05/28/21 10:03, Chapman Flack wrote:
> I still think it would be highly desirable for the JDK itself to
> adopt some such mechanism, if it can be made sufficiently non-cumbersome,
> and perhaps limited just to file operations

... and Process / ProcessHandle operations 


I am trying to enumerate, in my head, how many kinds of operations
there really needs to be some API for applying filters to, in a post-SM,
JPMS encapsulated world.

As far as effects a JVM can have on the observable outside world,
there are: native actions (and --enable-native-access), file operations
(and there is -Djava.nio.file.spi.DefaultFileSystemProvider), socket
operations (and there are SocketFactories, though how to set them is
undocumented and might fall victim to JEP 403), and process operations
(how to filter those? only instrumentation?).

Am I missing some?

It seems to me that a lot of the complexity of the permission model
in the pre-JPMS-encapsulation world involved protecting actions that
you might not otherwise care about except that they were all needed
to make "self-protecting managers" possible, without which the manager
could be defeated and then allow actions you'd care about.

If JPMS encapsulation can take over most of that busy-work, does that
perhaps mean the set of JDK operations that an application might
want/need to intercept and filter shrinks down to some concisely-enumerable
set of operations that have external effects?

I am not sure ... thinking aloud.

Regards,
-Chap


Re: JEP 411: Missing use-case: user functions in an RDBMS

2021-05-28 Thread Chapman Flack
Hi,

On 05/28/21 06:09, Ron Pressler wrote:
> Before getting into alternatives and the vision for what would be possible
> post-SecurityManager, it would help to explain what the use-case and 
> requirements are.
> 
> When we talk about untrusted code we usually mean code that you believe
> might be malicious and intentionally try to break through any restrictions
> you place on it and attack you by any means, including denial-of-service,
> while trusted code is assumed to not be malicious.
> 
> From what you’ve written I gather that you only intend to run trusted
> “plugins", but wish to restrict their operations so that they don’t break
> some application invariants and accidentally interfere with its operation.

It seems to me that PostgreSQL's trusted/untrusted distinction (which is
a distinction baked into the core PostgreSQL project and therefore common
to all of the different programming-language supporting extensions like
the Java one that I maintain) is aimed at a sort of intermediate threat
model.

The key consequence of whether a PL is declared to PostgreSQL with or
without the TRUSTED keyword is which database user identities will be
able to CREATE FUNCTION in that language. If it is not declared trusted,
only the database superuser can create functions using it. If it is
declared trusted, the database superuser will be able to GRANT USAGE ON
LANGUAGE ... to other database user identities, and they will then be
able to CREATE FUNCTION in that language.

Here it matters that "database user identities" are usually a pretty small
set. Acme Corp's customers won't all have database logins; they probably
interact with it through a web app that uses its own credentials for a db
connection. The few people with database logins are probably all on Acme
payroll, and relatively trusted. If Acme's DBA has said GRANT USAGE ON
LANGUAGE java TO bob; then probably Bob is not expected to go installing
malicious Java functions. Bob is probably a developer and expected to
apply reasonable skill at writing safe ones.

The functions, once installed, may be /executed/ by a larger number of
database IDs, including possibly via the web apps, so might be executed
with /inputs/ crafted as maliciously as external attackers can dream up.

So I think it might be said (perhaps the core PostgreSQL devs would hold
otherwise) that it's /essential/ for the mechanism to be adequate to
protect against oversights and mistakes in Bob's code or the libraries
he relies on, including mistakes that might be exposed to malicious
external inputs. It's /desirable/ for the mechanism to be robust
against a malicious Bob himself, but I'm not sure how many, if any, of
PostgreSQL's available PLs could be rigorously proven to be so.

> If that is the case, would a “shallow” sandbox, that restricts which APIs
> are available to the plugin (e.g. only expose special APIs to interact
> with files that go through filtering mechanisms) rather than restrict 
> low-level operations where they “bottom out” before being passed to the OS, 
> suffice

It's possible a new design in a green field would be able to take that
approach. One thing I should have mentioned, and forgot to, is that there's
an actual ISO standard, ISO 9075-13, SQL Routines and Types Using the
Java™ Programming Language, constraining how this stuff has to work.
That's kind of unique among the extension languages; the maintainers of
PL/Python or PL/Ruby, lucky devils, can follow their own visions of what
SQL functions in those languages should look like.

9075-13 certainly doesn't say anything about a limited or special API
that the function will be required to use. That would be a disruptive
change to arbitrary amounts of standard-compliant code. (Naturally, as
the standard was developed back when nobody thought the J2SE security
architecture would be going away, it would have been assumed that the
regular API could be used and permissions would control it.)

That said, it might be about time for working group 3 to convene for
another look at 9075-13; it hasn't been updated in a while, and I don't
think it groks JPMS yet either; user code is treated as classpath code.
The PostgreSQL core team has a rep on that working group, so maybe it
will be possible to plant that idea. I don't think these things move
very quickly.

Still, I think a change as drastic as "you must now change the API you
use to be some different limited version" could be a tough sell.

> While a complex, stack-dependent, deep sandbox *could* be used for plugins,
> permissions that don’t specify what is forbidden but what is allowed
> effectively also severely limit the use of third-party libraries, that
> for example, might want to do benign operations with their own files,

Well, the chief cause of that problem has historically been that the
third-party library devs have been sloppy about getting doPrivileged
where it belongs ... or, to put it more charitably, they haven't been
given any way less cumbersome than 

Re: JEP 411: Missing use-case: user functions in an RDBMS

2021-05-28 Thread Ron Pressler
Hi.

Before getting into alternatives and the vision for what would be possible
post-SecurityManager, it would help to explain what the use-case and 
requirements are.

When we talk about untrusted code we usually mean code that you believe
might be malicious and intentionally try to break through any restrictions
you place on it and attack you by any means, including denial-of-service,
while trusted code is assumed to not be malicious.

From what you’ve written I gather that you only intend to run trusted
“plugins", but wish to restrict their operations so that they don’t break
some application invariants and accidentally interfere with its operation.

If that is the case, would a “shallow” sandbox, that restricts which APIs
are available to the plugin (e.g. only expose special APIs to interact
with files that go through filtering mechanisms) rather than restrict 
low-level operations where they “bottom out” before being passed to the OS, 
suffice (*not* the one in my article, which is just intended for inspiration, 
and allows reflection without actually fully isolating it)?

Deep sandboxes, simple or stack-dependent, are useful for very “rich” code,
that is potentially very big and possibly contains arbitrary third-party
libraries, while shallow sandboxes are more suitable to limited plugins.

While a complex, stack-dependent, deep sandbox *could* be used for plugins,
permissions that don’t specify what is forbidden but what is allowed
effectively also severely limit the use of third-party libraries, that
for example, might want to do benign operations with their own files,
and so effectively only allow very limited plugins. The result is a costly
mechanism that is overkill for what it’s used for.

— Ron

> On 28 May 2021, at 02:35, Chapman Flack  wrote:
> 
> Hello, I see I am another person relatively late to stumble on this
> "well publicized" JEP. (I am not sure how to recommend the publicity
> could have been better handled, but apparently the avenues that were
> used aren't ones that reached me.)
> 
> I maintain, on a volunteer basis, the extension for Java server-side
> functions in the PostgreSQL RDBMS [1].
> 
> I got the news of this JEP through occasionally visiting the JDK 17
> page to see what JEPs are proposed and targeted that might be of use
> in the project, and one day I visited (could have been as late as May 17
> according to the Wayback Machine) and there was nothing of great
> interest (though I have some pleasant ideas for sealed classes and I
> really wish JEP 412 were done incubating!), and I didn't check back
> until just recently, and then I looked and saw this JEP.
> 
> I've read through the very long "Missing use-case: monitoring/
> restricting libraries" thread, and some of the points raised there
> have echoes here.
> 
> Any PostgreSQL server-side function implementation for a language foo
> will be expected to say it is a "trusted" or "untrusted" language (or
> provide both) as defined in the PostgreSQL docs [2].
> 
> A "trusted" one is expected to restrict certain actions (access to the
> server filesystem, perhaps network connections, etc.).
> 
> OS-level controls are too coarse because the RDBMS process that the
> language extension gets dlopened into certainly has reasons of its own
> to manipulate files and sockets.
> 
> It might, perhaps, be shown that every available trusted language for
> PostgreSQL could be imperfect or exploitable in some way; I think that's
> beside the point, which is that they all are meant to take credible
> steps to supply the expected layer of cheese with whatever small holes
> may be present.
> 
> In the current architecture, Java backend functions can be restricted
> with very fine grain, anything that a PolicyFile can specify.
> 
> It looks as if I will have to do a maintenance release, which will
> have to supply the extra -Djava.security.manager=allow when running
> on 17 (and spam the RDBMS log file with the apparently unsuppressable
> warning every time a JVM starts [3]), and then I will have to detect
> whatever subsequent Java release "degrades" the classes, and refuse to
> execute trusted functions on that release or later.
> 
> Beyond that, I'll need to begin on some rearchitected major release
> to be able to meet the requirements some other way.
> 
> Suppose I relax the requirements to merely restricting filesystem
> and network operations. Will there be any simple, reliable way for
> me to install some handler to filter those? I have seen JVMTI
> instrumentation suggested. I suppose an interposing FileSystemProvider
> could be an option for filesystem operations. SocketFactory and
> ServerSocketFactory might offer ways to interpose on network
> operations, except that there seems to be no documentation of how
> the default factories are to be set: "specified by environment-specific
> configuration mechanisms ... a framework could use a factory customized
> for its own purposes" doesn't seem quite sufficient. I could be