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.