Hi Fred,

I've cc'd Brian and river-dev.

Here's a message I've been working on, your right about Principals mattering. In fact, I've reconsidered and think Security Delegates and policy concurrency (non blocking) matter more than policy revoke-ability, I considered enlisting GC to perform automatic silent Permission Grant revocation, however it doesn't make sense from a security perspective, a reference is too easily held by a remnant object.

This is difficult to conceptualise, especially since Applets focused on CodeSource and Java's early focus on CodeSource policy grants are ingrained.

For a moment, take a simplistic view and forget there are some (not many) existing JVM permission's that don't let references escape.

A thread, combined with insecure object references allows a misbehaving object to transfer information out of the system on an ongoing basis, I want to prevent that. EG: I don't want a remnant object retaining a reference to my webcam and the network transferring images over the network unbeknownst to me, every time I invoke a method on that object or reading the event queue or something else nasty. Even if the Service has authenticated itself with a certificate. So yes, your right, the Principal can be used for effective revocation if used in combination with a Delegate.

The revokeable policy doesn't need to be in River's public API.

I'm trying to get my head around the pros and cons of a particular choice, for Permissions in relation to Security Delegates and Proxy's. (Option 2 is my preferred)

Options:

  1. Use fine grained ProxyPermissions, mirroring existing JVM
     permissions, due to the performance cost, the checkPermission
     result needs to be cached for each AccessControlContext, until
     there is a revocation.  The drawback here is complexity of a
     complete new batch of ProxyPermissions for application developers
     to learn. This model assumes the delegates hold all required JVM
     Permissions.  It wouldn't support revocation for existing
     services.  So it looks like I can rule out this model. OR
  2. Use some very simple course grained ProxyPermission's, to ensure
     revocation.  These ProxyPermissions would be very simple ("disk",
     "network", "auth", etc).  The Security Delegates would use these
     to guard the methods of security sensitive objects, like
     InputStream, OutputStream, Socket, etc,  The purpose of the
     security delegate is to prevent references to sensitive objects
     escaping into untrusted code, with encapsulation and permission
     checking every method invocation against the simple coarse grained
     ProxyPermission's (very fast with new concurrent policy provider,
     bad with existing due to contention).  SecurityDelegates would
     have their own archive, delegates.jar, which could be given
     permission grant's with principals, Delegates can perform
     privileged actions on behalf of proxy code, so Permission's
     granted to delegates determine the bounds of untrusted code
     functionality.

Untrusted proxy code would not directly be given any permission other than a ProxyPermission (with some exceptions), this ensures the only way for the proxy's to operate is via delegates. Delegates execute anything that requires a JVM Permission on behalf of the proxy via do Privileged.

Option 1 is a direct ProxyPermission grant model, where the ProxyPermission's themselves control what untrusted proxy code can do.

Option 2, uses an indirect Permission grant model, where JVM Permission's are granted to delegates, limiting the functionality of untrusted code, in this case the ProxyPermission are there to enable or disable proxy access to functions delegates provide (you hinted at this I believe), this can be done via principals or revocation.

In the case that dynamic permission grants, only apply to proxies, we don't require existing implementations to change their Permission Constraints, instead, we detect which ProxyPermission's are required, grant those to the proxy, and grant everything else to the delegates and ensure we have delegates enabled in the system? (Only works with Option 2).

What do we do when we detect a JVM permission, for which there is no delegate? Many JVM permission's are not practical for handling with delegates, eg Reflection. Do we have a configuration value that decides the behaviour of the platform? Eg by default we don't grant a JVM Permission where there is no corresponding delegate, but the platform can be enabled to grant the permission, if required, which is a security risk.

Option 2's view of the world, is that references to sensitive objects shouldn't be allowed to escape into untrusted code, that while the code determines the Permissions needed, access to functionality, should be limited by the Subject's Principals, not by the code, so the ProxyPermission's can be very simple and are basically just switches to turn off access to mostly predetermined functionality set by delegate policy grants. This option also treats all untrusted code alike, either code has access to simple categories of functionality via delegates or it doesn't at all. When untrusted code has access to delegates, it's the executing principal and delegate's traditional JVM Permission's which limit functionality, once the proxy has a ProxyPermission.

The reason that using Principal grant's alone without delegates and ProxyPermission's is inadequate, is the untrusted code can keep references it obtains while it has elevated privileges, executing as a subject, to later perform operations unchecked, with sensitive objects when it obtains a thread and doesn't have elevated permission.

So I'm reconsidering whether two proxy's, having the same codebase, can share the same classloader with Option 2? That decision would have to be made by the codebase developer? If the proxy codebase doesn't utilise static variables then there is no reason not to share the same classloader? Since the delegates prevent sensitive object references escaping into untrusted code, Subjects can be used to determine access, both in grants to delegates and proxy's.

Can we use bytecode analysis to determine that no static variables are present in the CodeSource? Or is the developers assertion enough?

What could code do with static variables anyway, if it can't get access to sensitive object references, only share information with other proxy's? It doesn't seem a big concern.

Proxy 1, is authenticated then verified, permission's advised in constraints are granted for Principal's to delegates, ProxyPermission required by any constraint Permssion's are also granted for Principal's. Then the proxy's operations are performed as a Subject.

Proxy 2 arrives, is unmarshalled into the same classloader as Proxy 1, but hasn't been authenticated, what can the proxy do? If it isn't executed as a Subject, it cannot attain the ProxyPermission's granted to Proxy 1. Once Proxy 2 has been authenticated and verified, it can be given permission grants, it can be executed as a Subject. If proxy's aren't executed as a Subject, they have no Permission.

So in this case we don't need to revoke the Permission Grant, since it is only effective when the code is executed as a Principal.

However it makes sense from a memory and performance perspective to remove Permission Grant's when they're no longer required, since they all must be looped over. In that case when a class doesn't have any active proxy objects, the Permission Grant's for that class should be removed. How can we tell that? We'd have to count the proxy objects for each class, by registering and de registering proxy objects?

Or could we lease the Permissions for the proxy? Every time a new proxy for a particular class comes in, it renews the lease for the PermissionGrant. How could the client refresh the lease? If the lease is not maintained the PermissionGrant is removed. I'm not sure this is desireable either, I want something that has little application programmer impact any ideas?

So in summary, it's the Code that determines what Permission's are required, but it's the Principal that determines whether that Permission should be granted and it's the Delegate and Security infrastructure that should prevent references to security sensitive objects escaping into untrusted code, by controlling what is granted via the dynamic policy.

Oh and the really neat part, neither the service nor the client needs to be aware that ProxyPermission's exist for Option 2. They can be managed secretly, behind the scenes.

Your time is much appreciated, I understand you probably don't have much time available to respond, if you do think of something please let me know.

Best Regards,

Peter.






Reply via email to