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.