JEP411: Missing use-case: Monitoring / restricting libraries

Peter Firmstone peter.firmstone at zeus.net.au
Thu Apr 29 12:06:37 UTC 2021


Having implemented SecurityManager and Policy providers, I'd like to 
comment on some of the assessments, some thoughts:

  * Poor performance, this is specific to the Java Policy
    implementation, I have addressed this in my implementations,
    performance impact is imperceptible, I know how to address it.
  * Brittle permission model - Agreed, it is brittle.
      o Developers should use doPrivileged blocks to make security
        sensitive calls, so only one domain is on the call stack. Agreed
        when they don't do this it causes viral permission expansion.
      o Implementing Deny would address the example given.
      o Un-trusted code should never be run on the JVM, however some
        code is more trusted, or well audited, so we may wish to limit
        code that doesn't require privileges, based on principle of
        least privilege.
      o Is there a way to simplify Permission's?  We can write tools to
        generate policy files (I have).
  * Difficult programming model
      o If the library developer uses doPrivileged blocks and documents
        the permissions, then the application code doesn't require those
        permissions, as it is not on the call stack.
      o Agreed that most developers don't do this.
      o I use a tool to generate policy files that capture the viral
        growth of permissions, these still require some editing, eg to
        add system properties.

Is there a simpler way to limit permissions of library code?

I have gotten so used to secure coding, because we use it, I don't find 
it difficult, writing non blocking or good concurrent code is more 
difficult and developers make lots of mistakes with race conditions, 
visibility and synchronization.

There are good static code analysis tools that identify poor coding 
practices, the same tools could be updated to include secure coding 
practices as well, to address viral permission expansion.

Perhaps if we instead address the performance and usability issues, we 
could improve adoption,so it adds to Java's appeal, rather than 
detracting from it?

Regards,

Peter.

Comments and code from one of my policy implementations (I have a few 
policy implementations that use the decorator pattern to add 
functionality, like dynamic permission grants):

* If there is sufficient interest, we can implement a DENY clause,
  * in this case DENY cannot apply to GRANT clauses that contain
  * {@link java.security.AllPermission}, the domains to which a DENY clause
  * would apply will be a less privileged domain.  For example a user 
could be
  * granted SocketPermission("*", "connect"), while a DENY clause might
  * list specific SocketPermission domains that are disallowed, where a 
DENY
  * clause has precedence over all GRANT clause Permissions except for 
AllPermission.


@Override
     public boolean implies(ProtectionDomain domain, Permission 
permission) {
         if (permission == null) throw new 
NullPointerException("permission not allowed to be null");
         if (domain == myDomain) {
             PermissionCollection pc = myPermissions;
             return pc.implies(permission);
         }
         Class klass = permission.getClass();
         // Need to have a list of Permission's we can sort if 
permission is SocketPermission.
         NavigableSet<Permission> perms = new 
TreeSet<Permission>(comparator);
         PermissionGrant [] grantRefCopy = grantArray;
         int l = grantRefCopy.length;
         /* Check for privileged grants first to avoid recursion when
          * privileged domains become involved in policy decisions */
         for (int j = 0; j < l; j++){
             PermissionGrant ge = grantRefCopy[j];
             if (ge.isPrivileged()){
                 if (ge.implies(domain)){
                     return true;
                 }
             }
         }
         /* Merge the static Permissions, check for Privileged */
         PermissionCollection staticPC = null;
         if (domain != null) {
             staticPC =domain.getPermissions();
             if (staticPC != null){
                 Enumeration<Permission> e = staticPC.elements();
                 while (e.hasMoreElements()){
                     Permission p = e.nextElement();
                     // return early if possible.
                     if (p instanceof AllPermission ) return true;
                     // Only add relevant permissions to minimise size.
                     if (klass.isInstance(permission) || permission 
instanceof UnresolvedPermission){
                         perms.add(p);
                     }
                 }
             }
         }
         /* Check less privileged grants */
         for ( int j =0; j < l; j++ ){
             PermissionGrant ge = grantRefCopy[j];
             if (!ge.isPrivileged()){
                 if (ge.implies(domain)){
                     Collection<Permission> c = ge.getPermissions();
                     Iterator<Permission> i = c.iterator();
                     while (i.hasNext()){
                         Permission p = i.next();
                         // Only add relevant permissions to minimise size.
                         if (klass.isInstance(permission) || permission 
instanceof UnresolvedPermission){
                             perms.add(p);
                         }
                     }
                 }
             }
         }
         return convert(perms).implies(permission);
     }

On 28/04/2021 8:19 pm, Lim wrote:
> On Wed, Apr 21, 2021 at 8:38 PM Ron Pressler <ron.pressler at oracle.com> wrote:
>> Its current events might be not have everything you want, but will be expanded, in
>> part to address the functionality that will be lost with the removal of Security Manager.
> I agree that monitoring needs to be improved since there is a lack of
> monitoring APIs except for JFR. Until those monitoring APIs are on par
> with the usage of SM "monitoring", it makes no sense to remove without
> providing alternatives.
>
>> Libraries that can disable the Security Manager aren’t able to circumvent OS-level
>> sandboxing. If you’re not afraid of that, then they’re trusted and JFR is superior;
>> if they’re untrusted, then configuring the Security Manager correctly for untrusted rich
>> libraries is very difficult.
> Since you said that it cannot circumvent OS-level sandboxing, what
> will prevent those
> libraries to monitor if there is JFR active and become dormant until
> there is no JFR
> present, then it will execute the malicious behavior; Or, the library
> attempts to hide
> or render the JFR useless so that it will not be recorded and noticed?
>
> On Wed, Apr 21, 2021 at 8:55 PM Ron Pressler <ron.pressler at oracle.com> wrote:
>> For rich libraries and applications, your best bet is an OS-level sandbox. The Security Manager
>> might give you a false sense of security.
> Yes, OS-level sandbox is good but can it be scalable for many types of end
> users that have different OS and hardware environments? In addition, how many
> end users out there have used sandbox to isolate their desktop applications
> except if the program has built-in sandbox such as web browsers? Programs
> such as Docker does not count.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20210429/4a6e6ea9/attachment.htm>


More information about the security-dev mailing list