You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Peter Firmstone <ji...@zeus.net.au> on 2010/08/26 13:09:18 UTC

ProxyPermission's

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.