Trust is the hard bit. Segmenting parts of the service.jar into service-api.jar and service-dl.jar spreads the trust analysis from 1 jar to 3 (up from 2). What we'd like to believe is that service-api.jar is harmless. What we need to do (and I believe you are) is make sure that service-api.jar is completely quarantined as being non-trusted.

What I'd like to understand is if we can/will make the statement that service-api.jar can not ever require any authorization, or if we will provide a mechanism for applying different permissions to the different ProtectionDomains that we will now segment the code into.

Gregg Winderly

Peter Firmstone wrote:
Thanks Gregg,

It's time to change how we use ClassLoaders and ProtectionDomains, by splitting apart concerns of Visibility and Security. Forget about Preferred Classes for a moment.

I'm effectively isolating downloaded code's Permissions, by placing each codebase within it's own ProtectionDomain, typically when network classes are given their own ClassLoader for isolation, this isolation is provided by the ProtectionDomain. But unlike an applet, I want the Service API code to be visible by all Application and Proxy Classes, so it must go into the same Parent ClassLoader for visibility.

Since the Service API code can't see Application or Proxy classes, only platform classes and other Service API classes, I'm also leveraging ClassLoader visibility for some additional security benefit.

I want the security isolation of an applet the ProtectionDomain provides, but not the visibility isolation an individual ClassLoader provides for Service API.

By default I don't want any network downloaded Service API code to have any permission whatsoever. I had even considered eliminating the possibility of granting any permission to Service API, by using a static ProtectionDomain

The ClassLoader structure proposed, is like this:

              System ClassLoader (Java)
                      |
             Extension ClassLoader (Java Extensions, jsk-policy.jar, etc)
                      |
Jini Platform ClassLoader ( Apache River, Application Service API)
                      |
       _______________|_______________________________________
      |                            |             |            |
Application ClassLoader         Proxy CL      Proxy CL      Proxy CL
(Service's, Apps, Libraries)

Currently we dynamically grant permissions to a ClassLoader space, with a prerequisite set of Principals.

I'm in the process of adding new grants, in addition to ClassLoader grants and Principal grants:

ProtectionDomain grants - useful for proxy instance specific grants.
CodeSource grants - specific to a CodeSource, may be shared by many proxy's
Certificate[] grants - specific to a Certificate chain can apply to many CodeSource's

We will also be able to combine the grants, this particular combination will be extremely useful:

Certificate[] and Principal[] grants

This will apply to situations that combine developers we trust and Principals we trust.

The ClassLoader structure above is relatively simple, it allow's smart proxy's to have complete visibility and security isolation, from application and Service API code. In effect we can have one Service API loaded in the Jini Platform ClassLoader space, an application using a proxy, it can't see directly, through the Service API.

Currently we're extending the jar conventions of service construction to include:

Implementation jar: service.jar (Application ClassLoader shared space) Specification/API jar: service-api.jar (Jini Platform ClassLoader shared space) Download jar: service-dl.jar (Proxy ClassLoader isolated space)

The only time proxy's can share a ClassLoader is if their Principals and CodeSource is identical, because not only will we be sharing the ClassLoader, but the ProtectionDomain also.

I haven't figured out how to an Application can be started in a child ClassLoader yet, so any help you can provide would be much appreciated.

Hope this helps clarify things a bit more.

Cheers,

Peter.

Gregg Wonderly wrote:
My understanding/recollection of what currently happens, is that any class that the client already has loaded, will be used by the proxy as long as it is not preferred, because of the classloader hierarchy. This means, that non-preferred classes that a client has in the jars of its classpath, have been assumed to be safe, and having them in the classpath indicates, in a sense, trust in the content and activities of the code in such jars.

I don't think it's a good idea to "load" classes from network downloaded jars into the system class loader arbitrarily.

The convenience of having a lot of these things automated is a good thing, but I think the default must be that network downloaded code has no permissions explicitly granted by placing that code into a classloader that is not associated with a thread of execution that is based on the downloaded codes SecurityContext.

Gregg Wonderly

Peter Firmstone wrote:
Actually this might cause a problem if the proxy has been granted greater priviledges than a calling thread's Principal (a user) running with a lesser set of Permissions than the proxy, it causes all SecurityManager checks by the proxy to throw Security Exceptions.

Does this mean restricting the PermissionDomain of the *-api.jar is the wrong thing to do?

Should it be allowed DynamicPolicy grant's?
Perhaps it should be given the same Permissions as the most privileged proxy instead, using the fore mentioned ClassDep tool to verify the *-api.jar files don't depend on any security sensitive classes prior to loading?

When performing dynamic grants to a class, get the classes interfaces and do the dyanamic grant's on them too.

What do you think?

Peter Firmstone wrote:
Actually on Second thoughts, this security concern is unfounded (paranoia perhaps, security is hard!), the ProtectionDomain of the *-api.jar will be on the execution stack, the actual Permissions will be those common to all ProtectionDomain's on the caller's stack, so therefore having a ProtectionDomain with no permissions assigned to a *-api.jar will cause the calling thread to have no permissions (as the proxy sees it).

Therefore a proxy, if it is to utilise it's own permission grants, it will need to use AccessController.doPrivileged()

That sounds better.

Anyway there will be no Permissions granted to any *-api.jar, ever as I'm going to utilise the pre java 1.4 ProtectionDomain constructor, that specifically prevents and excludes dynamic Policy grants. It won't even consult the Policy.

I'm modifying DynamicPolicy to include grants by Certificate[], an *-api.jar that is signed by a trusted certificate chain, still wont gain any permissions. Can anyone see that as a problem?

The *-api.jar classes must not have dependencies on anything outside of the Jini Platform, Java Platform or other *-api.jar classes. The reason for this restriction, is if Someone want's to use OSGi or has a dependency on another version of a library, the *-api.jar importing an incompatible version, would obscure it's visibility and cause a runtime error.

These restrictions shouldn't cause a problem for people as they're easy to design around. It makes security simpler for developers too. - You don't have to worry about the security of the code in *-api.jar

Cheers,

Peter.

Peter Firmstone wrote:
Dennis Reedy wrote:
Chris, Dennis & Greg, your all spot on with the Service-spec.jar, I'd like to add something to the jar Manifest of these Service Interfaces, to ensure River loads it into the top level ClassLoader. Any suggestions?

Why not just support the convention instead of adding configuration?

Ok.

There is one Security Concern that I will have to address with this Approach:

ClassLoader Structure:

                System ClassLoader
                        |
               Extension ClassLoader (incl jsk-policy.jar)
                        |
Jini Platform ClassLoader (incl jsk-platform.jar, *-api.jar)
                        |
         _______________|________________
        |                                |
Application ClassLoader         Proxy ClassLoader's


The *-api.jar files will be placed into Jini Platform ClassLoader, so the only files visible will be the jini platform classes, java platform classes and any other *-api.jar classes.

The *-api.jar classes will have their own ProtectionDomain's without any Permissions.

However this isn't enough to protect us from code that might be included in the *-api.jar's that use the calling Threads Permissions to perform security violating actions.

Due to these security concerns, we need to place some restrictions on the API classes:

  1. They must not be allowed to depend on anything other than Jini,
     Java Platform and other Service-api.jar's
  2. They must not be allowed to depend on any Platform classes that
     could cause a Security Violation.

The Service API code really needs to be verified before loading, to ensure that it does not utilise any platform classes that perform security sensitive operations.

The ClassDep tool can run a Dependency Analysis on any *-api.jar to ensure that no security sensitive classes are accessed, prior to loading.

There is some residual risk that as the Java platform evolves, new classes that perform Security Sensitive actions will be added, which means the list of restricted classes will need to grow over time.

Could the list itself be contained in a Maven Repository, we could sign, such a list.

Thoughts?

Peter.















Reply via email to