An implementation would work something like this:

  1. When a djinn node starts, it discovers a Registrar (lets say it
     uses secure discovery to eliminate registrar proxy unmarshalling
     attacks.).  The registrar would have method constraints enabled,
     limiting who can submit services.
  2. The node then looks up a Security Policy Advisory service, it
     chooses one that can authenticate as an Administrator.
  3. The client node then hands back a proxy (RemotePolicy service)
     that the SecurityPolicyAdvisory service (using MethodConstraints
     again to restrict access) uses to update the local security
     policy, running as the administrator subject.  The RemotePolicy
     service implements Unreferenced, when the SecurityPolicyAdvisory
     service is down, DGC will notify the RemotePolicy that it has
     become unreferenced, so it can lookup another Security Policy
     Advisory service and continue keeping it's security policy up to date.

(One reason explaining why I'd like to secure DGC).

What use is a Security Policy Service?

An example:

  1. Lets for a moment imagine a hypothetical secure djinn environment,
     this may span a number of physical locations where those locations
     are connected via the internet, Registrars are used to unite this
     environment.  This secure djinn environment may also include a
     number of different administrators, who represent cooperating
     entities.  Each entity controls his/her own Registrar's and
     restricts the services registered to those he/she owns.  Any other
     known entity may lookup any of the services on any registrar.
  2. Each entity signs their proxy codebases.
  3. Additional entity's join the group over time.
  4. Each entity has an Identity, represented by a Subject containing
     authentication Certificates and Principals.
  5. A security policy service would allow you to grant
     DownloadPermission, to all and any CodeSources signed with
     approved Certificates.  The policy can be updated to include any
     newly approved Certificates.  DownloadPermission is a misnomer, it
     prevents a class being defined, or loaded, it doesn't prevent it
     being downloaded, the jar file actually gets downloaded prior to
     the DownloadPermission check.  This is useful for preventing
     unmarshalling attacks from unknown attackers.
  6. The policy also allows the administrator to update Permission's
     granted to Principals.
  7. A number of Permission's can be granted based on Principals and
     CodeSource Certificate combinations.  Note this doesn't eliminate
     the need for a Service to verify it's proxy object or grant
     Permissions to proxy's dynamically, but it can be used to
     determine which GrantPermissions are allowed for such combinations.

To make it easier for clients to determine the Permission's a CodeSource might require we could add something similar to the following to our jar files:

OSGI-INF/permissions.perm

(org.osgi.framework.PackagePermission "javax.microedition.io" "import")
(org.osgi.framework.PackagePermission "org.osgi.service.io" "import")
(org.osgi.framework.PackagePermission "org.osgi.service.log" "import")
(org.osgi.framework.PackagePermission "org.osgi.util.tracker" "import")
(org.osgi.framework.PackagePermission "org.osgi.framework" "import")
(org.osgi.framework.PackagePermission "org.eclipse.equinox.internal.util.hash" 
"import")
(org.osgi.framework.PackagePermission "org.eclipse.equinox.internal.util.pool" 
"import")
(org.osgi.framework.PackagePermission "org.eclipse.equinox.internal.util.ref" 
"import")
(org.osgi.framework.PackagePermission "org.eclipse.equinox.internal.io" 
"export")
(org.osgi.framework.PackagePermission "org.eclipse.equinox.internal.io.impl" 
"export")
(org.osgi.framework.PackagePermission "org.eclipse.equinox.internal.io.util" 
"export")
(org.osgi.framework.PackagePermission "javax.microedition.io" "export")
(org.osgi.framework.BundlePermission "*" "provide")
(org.osgi.framework.BundlePermission "*" "host")
(org.osgi.framework.ServicePermission "org.osgi.service.io.ConnectionFactory" 
"get")
(org.osgi.framework.ServicePermission "org.osgi.service.io.ConnectorService" 
"register")
(java.util.PropertyPermission "*" "read")
(java.net.SocketPermission "*" "listen")


The above is an example of permissions.perm in an OSGi bundle jar file. OSGi calls these Local Permissions. The semantics of OSGi are slightly different with permissions.perm defining the maximum allowable Permission's for a bundle, which when empty is only limited by AllPermission, which is not really what we want.

But we could have something similar eg:

META-INF/permissions.perm

A client could parse this information to determine the Permissions a proxy requires, the administrator can restrict by way of GrantPermissions, the Permission's Principal's or clients are allowed to grant to proxy's.

Some food for thought.

Cheers,

Peter.



Peter Firmstone wrote:
When deploying nodes in a Djinn, how do you currently manage your security policies? How secure is your environment? Java can use URL based policies, but this is subject to spoof attacks and the URL cannot change without reconfiguring clients.

Currently the way the Java policy system works by reading in (parsing) policy files, with the local policy provider.

Java policy's are permissive, which means you start with only the jre and extensions having permissions, you then grant permission by CodeSource, Certificates and Principals in policy files.

Once security is relaxed, to tighten it requires a restart, impractical for a distributed environment, in reality it's designed for a local jvm.

A security policy service could be used by a codebase admin to restrict download permissions. An admin might also like to be able to put a limit on download size to avoid DOS and Domain spoofing attacks. In addition a ClassLoadingPermission would be useful to restrict class loading of CodeSource's to those signed with approved Certificates of trusted developers or partners. The admin might also determine what GrantPermission's can be made by different Principals.

Requirements of a distributed Security Policy Service:

  1. The security policy's need to be manageable in one location for
     administrators managing a number of nodes.
  2. There may be several security policy services in a single djinn,
     belonging to different cooperating entities, more than one
administrator http://nighthacks.com/roller/jag/resource/Fallacies.html
  3. All nodes belonging to an entity are configured to lookup the
security service based on identity with secure InvocationConstraints.
  4. Nodes are configured to register with a SecurityPolicy service
     that can authenticate with an administrator subject.
  5. Nodes retrieve a current policy from the SecurityPolicy service
  6. The SecurityPolicy service notifies with a RemoteEvent when the
     security policy has been updated.
  7. Nodes update their security policies when notified of change.
  8. Security policies must be idempotent, when a change is made to the
     policy, clients must update the entire policy, they cannot make
     incremental sequenced or ordered changes.
  9. The SecurityPolicy service can only provide policy advise based on
     CodeSource, Certificate's and Principals.  They cannot make proxy
     trust decisions or provide policy advise for Proxy's (ClassLoader
     based dynamic permission grants), other than GrantPermission's
     which are those that a local Subject has permission to grant to
     proxy's.
 10. Client nodes must update their security policy without shutting
     down, a restart would cause all clients to do so at the same time
     which creates issues with multicast packet storms, so the policy
     must be capable of removing grants absent from the updated policy
     without restarting.
 11. A SecurityPolicy service would supplement the existing dynamic
     grants used for Proxy's, it's important to realise that dynamic
     proxy permission grants are a local concern and are granted to the
     proxy's ClassLoader.  Cleaning of grants deleted from the policy
     made by the SecurityPolicy service must not remove dynamic grants
     made to proxy's.

One important thing to remember regarding policy updates, some permission grants even though they have been removed (depending on the type of permission granted) fundamentally allow references to escape after a security check is made, so once a reference to a security sensitive object has been released, the SecurityManager has no further control over it. DelegatePermission's and Delegate's are intended to address this issue, using Li Gong's method guard pattern (Li Gong: Inside Java 2 Platform Security, 2nd Edition, Page 176, 2nd last paragraph ISBN: 0201787911). Programming with method guards in this fashion also eliminates references escaping, making it easier to audit code for security. To do so without degrading performance requires the new InternetSecurityManager and DynamicConcurrentPolicyProvider currently under development.

I'm also contemplating the possibility of a LoginModule service.

Cheers,

Peter.










Reply via email to