<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, May 27, 2021 at 8:36 PM Chapman Flack <<a href="mailto:chap@anastigmatix.net">chap@anastigmatix.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello, I see I am another person relatively late to stumble on this<br>
"well publicized" JEP. (I am not sure how to recommend the publicity<br>
could have been better handled, but apparently the avenues that were<br>
used aren't ones that reached me.)<br>
<br>
I maintain, on a volunteer basis, the extension for Java server-side<br>
functions in the PostgreSQL RDBMS [1].<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">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).</div><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><div class="gmail_default">Anyway here it is:</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">---------- Forwarded message ---------<br>From: <strong class="gmail_sendername" dir="auto">David Lloyd</strong> <span dir="auto"><<a href="mailto:david.lloyd@redhat.com">david.lloyd@redhat.com</a>></span><br>Date: Sat, May 22, 2021 at 9:11 AM<br>Subject: Re: JEP proposed to target JDK 17: 411: Deprecate the Security Manager for Removal<br>To:  <<a href="mailto:mark.reinhold@oracle.com">mark.reinhold@oracle.com</a>><br>Cc: jdk-dev <<a href="mailto:jdk-dev@openjdk.java.net">jdk-dev@openjdk.java.net</a>><br></div><br><br><div dir="ltr"><div dir="ltr"><div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, May 21, 2021 at 6:04 PM <<a href="mailto:mark.reinhold@oracle.com" target="_blank">mark.reinhold@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The following JEP is proposed to target JDK 17:<br>
<br>
  411: Deprecate the Security Manager for Removal<br>
       <a href="https://openjdk.java.net/jeps/411" rel="noreferrer" target="_blank">https://openjdk.java.net/jeps/411</a></blockquote><div><br></div><div><div>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.</div><div><br></div><div>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).</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Thus I would suggest not deprecating all of SecurityManager, rather just the following:</div><div><br></div><div>* java.lang.SecurityManager#getClassContext - it is replaced by StackWalker</div><div>* java.lang.SecurityManager#getSecurityContext</div><div>* java.lang.SecurityManager#checkCreateClassLoader</div><div>* java.lang.SecurityManager#checkPermission(java.security.Permission, java.lang.Object) - the overload which accepts a "security context"</div><div>* java.lang.SecurityManager#checkPackageAccess</div><div>* java.lang.SecurityManager#checkPackageDefinition</div><div>* java.lang.SecurityManager#checkSecurityAccess</div><div>* java.lang.SecurityManager#getThreadGroup</div><div><br></div><div>...as well as their dependent methods and security checks.  These checks generally pertain to determining whether the application or its frameworks are trusted to perform certain operations, but are far less useful for user authorization, as far as I can determine.  I would probably even include the system property access methods as well - though I saw Peter arguing that those in particular were useful, I have my doubts, but that could obviously be worked out.</div><div><br></div><div>Further I would recommend the following change: make java.lang.SecurityManager#checkPermission(java.security.Permission) either a no-op or throw UnsupportedOperationException.  Ideally, SecurityManager and checkPermission() would be made abstract (and, for completeness, the SecurityManager constructor); perhaps after the deprecation period, such a change could be made.  It's a bit tricky here, because the deprecation policy doesn't seem to cover the case of making a concrete class or method abstract.</div><div><br></div><div>The remaining proposal would need slight modification in certain ways: for example, the security manager allow/forbid flags would still make sense and need to be retained, and the permission checks in socket and file system code would need to be retained.</div><div><br></div><div>After this change, SecurityManager would be decoupled from the stack-based access controller.  This means that any implementation of authorization would be the responsibility of third-party libraries.  The remaining JDK authorization checks would then be easily testable - much more so than today, because the contract becomes substantially simpler in the absence of AccessController - and still usable by third party security managers to perform user authorization checks on these native operations. And, it would still be possible for third parties to provide stack-bas<span class="gmail_default"></span>ed access control checks using StackWalker for an extra level of security with absolutely zero additional cost to JDK maintenance (and the burden of coping with the lack of doPrivileged would reside squarely on the third party).</div><div><br></div><div>As for JAAS, nobody would be happier than us to see it just go away, though that may be beyond the scope of this change.  The proposed scope locals give what is potentially a very good opportunity to employ a vastly superior means of propagating security context between tasks.  Under this proposal, a third-party security manager which uses a scope local security context for authorization would not only be a useful and measurable security improvement over an "unsecured" JDK, but would also likely be substantially more performant (and, if I may say so, reliable) than anything using JAAS today.  It should even be possible, in the future, to standardize on a new authentication and authorization identity propagation API using these mechanisms - at least in Jakarta EE and/or MicroProfile, if not in the JDK itself.</div><div><br></div><div>Essentially what I propose is only slightly departed from the current JEP 411 proposal, by introducing the exception of retaining certain permission checks and the security manager class itself.</div><div><br></div><div>Please give this compromise some consideration. Thanks!</div><div><br></div><div>[1] <a href="https://github.com/wildfly-security/wildfly-elytron" target="_blank">https://github.com/wildfly-security/wildfly-elytron</a></div></div><div>[2] originally: <a href="https://github.com/wildfly-security/security-manager/blob/master/src/main/java/org/wildfly/security/manager/WildFlySecurityManager.java" target="_blank">https://github.com/wildfly-security/security-manager/blob/master/src/main/java/org/wildfly/security/manager/WildFlySecurityManager.java</a></div><div>     - which is now: <a href="https://github.com/wildfly-security/wildfly-elytron/blob/1.x/manager/base/src/main/java/org/wildfly/security/manager/WildFlySecurityManager.java" target="_blank">https://github.com/wildfly-security/wildfly-elytron/blob/1.x/manager/base/src/main/java/org/wildfly/security/manager/WildFlySecurityManager.java</a></div></div></div></div><div><br></div></div></div></div></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>