river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Wade Chandler <hwadechandler-apa...@yahoo.com>
Subject Re: Service lookup without unmarshalling - details
Date Sun, 14 Dec 2008 21:08:50 GMT
----- Original Message ----

> From: Michał Kłeczek <michal.kleczek@xpro.biz>
> To: river-dev@incubator.apache.org
> Sent: Sunday, December 14, 2008 7:10:19 AM
> Subject: Re: Service lookup without unmarshalling - details
> 
> Hi,
> 
> This is a really interesting topic since it touches areas in River 
> architecture that have some holes. So these some of my thoughts:
> 
> 1. We cannot get rid of SecurityManager since then we would have an "all or 
> nothing" security - once we say we trust downloaded code it is not 
> constrained in any way. In Jini we only trust the service up to the level of 
> the permissions we dynamically grant to it.
>

I skipped over the call level security which needs to be address. OK,  still, I think we should
be able to tell the core to relax or constrict and only import services from 1) servers or
clients (connections) having this or that certificate (SSL) or credentials (Kerberos), 2)
particular signers of code bases, 3) any pluggable abilities such as a way to sign some unique
code base or attached security device, 4) specific classes and objects or URLs or any grouping
of those things. Technically unbinded because all that is pluggable. That makes good sense
in the cases where we have our own sets of services we code this way or that and don't really
care which way or how the services behave as long as they are ours within our system. Now,
in the cases where we need finer control or allow others to plug into our system then it gets
more and more needed and call level security should be usable.

Then, from a security and configuration stand point on finer grained details, SecurityManager,
Jini can provide security management through what ever means we need, but we are limited by
the hosting system and any means in which we can attach constraints, configuration files,
set another security manager, etc. Thus, if tooling can't do anything about that level of
access, then that limits that tooling and can be a known issue. Too it wouldn't just affect
tooling, but would affect things in any environment where Jini is to be used, so that is something
we'll have to deal with regardless. 

Obviously in standalone environments it is easier to deal with. In NB for instance as the
TopSecurityManager class is in bootstrap is should be in the system classloader, and then
delegate classloaders can be registered and unregistered using:
TopSecurityManager.register(SecurityManager)
TopSecurityManager.unregister(SM)

and that is our tie into NB I believe at this point through maybe Gregg has already been down
that path. Too, we can always try to get some API changes done to make it easier to register
and unregister delegating security managers. With NB it can be run with the security manager
turned off as well. Anyways, when we can tie into a manager we can make the security configuration
simple as we can add any constraints on the fly through any means we need...even some other
security file format. So, that is something we can provide in different forms in Jini, and
then the cases where such things can't be done we are out of luck and the user has to find
a way on their own...no way around that I believe.
 
> 2. ServiceLookup can be seen a solution to the problem of memory consumption 
> when processing large number of ServiceItems. But it cannot be seen as a 
> solution to the more general problem in Jini security - the possibility of 
> DoS type of attacks during deserialization. Even if we have something 
> like "never preferred" classes there is still a possibility for a service to 
> embed some data in an attribute that will cause the client to die (for 
> example a 5GB name).
> This looks really difficult to solve - on one hand you don't want to 
> deserialize a proxy (or any other object) - on the other hand you cannot 
> verify if you trust a proxy without deserializing it because you will not be 
> able to get a bootstrap proxy.
> Possible solutions:
> a) In short - PKI: the client and the service have to understand common data 
> formats, protocols and cryptographic algorithms and use them to verify 
> downloaded code and data. But the idea behind Jini was "the end of 
> protocols" - we just have to agree upon the Java interfaces we understand. Of 
> course it is not possible right now with River but keeping the set of 
> protocol/data formats definitions as small as possible is an important goal 
> IMHO.
> b) Get two objects from the lookup service - a proxy as a MarshalledObject and 
> a trust verifier that is deserialized without downloading any code. The trust 
> verifier would be used to verify (marshalled) real proxy. It could be done 
> for example by checking the digest of the marshalled real proxy. The downside 
> of this is that the client must know the data verification process so it 
> actually is no different than a)
> 
> When thinking about it I came up with an idea that it can be solved by having 
> a client use a third party to interact with a service. So the client would 
> not download any code. It would pass it's own proxy to the third party and 
> interact with the service there (since it cannot download a service proxy 
> into its own VM). In it's simplest form this "third party" can be just 
> another JVM process spawned by the client. The communication between the two 
> can be implemented as a LocalProcessEndpoint using System.in/System.out and 
> Process.getInputStream/Process.getOutputStream() to actually send data.
> 

My first thoughts are that would be overkill in most cases, and I don't mean that to be argumentative,
just my first thought. Seems we can have a simple API to set some limits on the code downloading
such as serialized size etc. Then we make it extensible so other applications can inject any
attributes and tests and checks they want. 

We can do a couple things, but on a high level we can 1) Extend ObjectInputStream and do some
things there and 2) Have a 3rd party stream which we inject under the ObjectInputStream which
we read from. We can then build a rule/state machine which we can build a customizable/implementable
(how ever we want to look at it) system where we can have some simple and workable defaults
that allow consumers/users to get off the ground more quickly and also to inject more rules
as they need them for their specific environment or custom systems.

With that and maybe some other things we do with ObjectInputStream and ObjectOutputStream
or JERI and endpoints, look at src/net/jini/jeri/*, or whatever we can technically create
such a system where if needed the extra security provided by such a 3rd party deserializer
could be created from that yet wouldn't have to be something we have to do to get a pretty
good system in place. So, we could do a lot to move River forward, and then later make those
more complex additions as extra value adds once we have some other things in place.

What do you think? Am I out in left field or does that sound like a decent starting point?

Wade


 ==================
Wade Chandler, CCE
Software Engineer and Developer, Certified Forensic Computer Examiner, NetBeans Dream Team
Member, and NetBeans Board Member
http://www.certified-computer-examiner.com
http://wiki.netbeans.org/wiki/view/NetBeansDreamTeam
http://www.netbeans.org

Mime
View raw message