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/10/18 03:08:38 UTC

Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Notes for fix:

DownloadPermission protects against unauthenticated downloads
ClassLoadingPermission - new Permission to protect against 
unauthenticated Class loading.

Issues we're addressing in the DOS hole:

    * Eliminate unauthenticated URL downloads.
    * Eliminate unmarshalling of unauthenticated code.
    * Eliminate execution of unauthenticated code.
    * Eliminate StackOverflowError's in the client thread, caused by
      sending spurious garbage over InputStream's.
    * Eliminate StackOverflowError's in the client thread, caused by
      substituted jar files or URL's from DNS cache poisoning attacks etc.

How?

    * Delay granting DownloadPermission, until remote endpoint has
      authenticated itself, we trust the remote endpoint to advise a
      suitable URL, if it authenticates.
    * Authentication by annotating a reflective proxy (additional to the
      Codebase String) from the remote endpoint, used for authentication
      and to provide CodeSource Certificate[]'s.  This may be different
      to the Service, if a remote object is marshalled elsewhere (eg
      another client).
    * Delay granting ClassLoadingPermission, until remote endpoint has
      authenticated itself and has provided the expected CodeSource
      Certificate[]'s
    * Perform unmarshalling in a controlled ExecutorService thread.

So all we're doing different is authenticating the remote end and if it 
authenticates permit downloading and classloading.

There is one more scenario to consider, currently this is a mechanism to 
protect against download and deserialization of unknown code for smart 
proxy's.  But what about Service that only use reflective proxy's and 
don't require downloaded code?

But what if we don't want to grant download permission or class loading 
permission to a Subject we authenticate?

Currently the unmarshalling code doesn't run as the Subject after 
authentication, this means the Permission grant's are only dependent on 
authentication, something Michal pointed out earlier when this was proposed.

Now this code can be easily changed so the granting permission operation 
is run as the Subject after authentication, this would allow us to 
distinguish between different Subjects.

The drawback is that performance won't be as good, but it seems the most 
logical and powerful approach.

What do you think?

There is one last obstacle, if Certificates are used to sign the jar 
files, how do you effectively prevent one Subject from using another 
Subject's signed CodeSource's if Code signing is used for isolation of 
separate Subjects namespaces?  A service could deliberately attempt to 
occupy the same namespace as another Service to attempt to gain 
information via shared static variables.  We need to prevent this occurring.

This has to be done with the ClassLoader, but during unmarshalling, the 
service proxy has not yet been verified.  The authentication proxy 
delivered with the MarshalInputStream may not have the same Subject as 
the Service, it could be a third party.

Could it be that when the smart proxy is unmarshalled, and executed as 
it's Subject, it must contain a Certificate matching the signer of the 
Codebase?

We're on the cusp of solving this problem, thoughts?

Cheers,

Peter.

Peter Firmstone (JIRA) wrote:
> Denial of Service during unmarshalling of smart proxy's
> -------------------------------------------------------
>
>                  Key: RIVER-362
>                  URL: https://issues.apache.org/jira/browse/RIVER-362
>              Project: River
>           Issue Type: Bug
>          Environment: Untrusted networks
>             Reporter: Peter Firmstone
>
>
> During unmarshalling of smart proxy's there's a period before the proxy has been verified (authenticated) where deserialization methods are executed on untrusted code, the potential exists for untrusted code to perform denial of service.
>
>   


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Thanks Michal,

If you log into JIRA, it has an upload feature, you can attach the code 
directly to the issue and grant an AL2 license at the same time.

https://issues.apache.org/jira/browse/RIVER-362

Cheers,

Peter.

Michal Kleczek wrote:
> Folks,
>
> I've managed to create a prototype implementation of the idea of annotating 
> classes with Modules.
> Working on this allowed me to learn quite a lot about inner workings of River 
> - the original implementation that I've presented before had to be modified 
> (not saying it had to be fixed :) ) but the main idea stayed the same. This 
> time I think it really covers more use cases.
>
> Shortly:
> 1. We allow annotating classes with Modules. A Module is an object responsible 
> for loading classes.
> 2. There is a new RMIClassLoaderSpi implementation which I called 
> ModuleClassProvider
> 3. ModuleClassProvider manages installed Modules
> 4. It also can load classes based on String annotations which are expected to 
> be either
> a) serialized and Base64 encoded Module - the Module is deserialized and 
> handled as any other Module annotation
> b) an old style list of URLs - class loading is delegated to 
> RequireDlPermProvider - in other words we either load classes from Modules 
> (which are verified for trust before use) or from URLs but then we require 
> appropriate DownloadPermissions
>
> Attached is a multi-module maven project. The modules are:
> 1. secure-marshall-stream (which is the implementation of all this + some not 
> yet finished additional code)
> 2. jsk-module-platform which contains modified Jini classes so that it all 
> works with existing Jini services (to be honest only ClassLoading really 
> needed to change. MarshalInputStream/MarshalOutputStream/MarshalledInstance 
> are changed only to avoid having serialized and Base64 encoded Modules as 
> annotations
>
> To run it you need to put jsk-module-platform before jsk-platform on the 
> classpath (and of course add secure-marshall-stream as well)
>
> Existing services can be exported with a ModuleExporter:
>
>     private serviceILFactory =
> 	new ProxyTrustILFactory(serviceConstraints,
>                                 RegistrarPermission.class);
>     private moduleTrustILFactory =
> 	new ModuleTrustILFactory(serviceConstraints,
>                                 null);
>
>     serverExporter = new ModuleExporter(new BasicJeriExporter(serviceEndpoint, 
> serviceILFactory), new BasicJeriExporter(serviceEndpoint, 
> moduleTrustILFactory));
>
> I've done some basic scenario testing which was running Reggie and Service 
> Browser installed by Jini 2.1 installer. Both Browser and Reggie policies did 
> not grant any DownloadPermissions.
> When exported with BasicJeriExporter lookup of ServiceRegistrar by the Browser 
> failed with missing DownloadPermission.
> When exported with ModuleExporter both Reggie and Browser used 
> ProxyTrustVerifier to verifify Modules.
>
> Note - this is strictly a prototype - no comments / junit tests / code reviews 
> and no real testing.
>
> If you have any questions / comments - you're very welcome.
>
> Michal
>
> On Monday 18 of October 2010 03:08:38 Peter Firmstone wrote:
>   
>> Notes for fix:
>>
>> DownloadPermission protects against unauthenticated downloads
>> ClassLoadingPermission - new Permission to protect against
>> unauthenticated Class loading.
>>
>> Issues we're addressing in the DOS hole:
>>
>>     * Eliminate unauthenticated URL downloads.
>>     * Eliminate unmarshalling of unauthenticated code.
>>     * Eliminate execution of unauthenticated code.
>>     * Eliminate StackOverflowError's in the client thread, caused by
>>       sending spurious garbage over InputStream's.
>>     * Eliminate StackOverflowError's in the client thread, caused by
>>       substituted jar files or URL's from DNS cache poisoning attacks etc.
>>
>> How?
>>
>>     * Delay granting DownloadPermission, until remote endpoint has
>>       authenticated itself, we trust the remote endpoint to advise a
>>       suitable URL, if it authenticates.
>>     * Authentication by annotating a reflective proxy (additional to the
>>       Codebase String) from the remote endpoint, used for authentication
>>       and to provide CodeSource Certificate[]'s.  This may be different
>>       to the Service, if a remote object is marshalled elsewhere (eg
>>       another client).
>>     * Delay granting ClassLoadingPermission, until remote endpoint has
>>       authenticated itself and has provided the expected CodeSource
>>       Certificate[]'s
>>     * Perform unmarshalling in a controlled ExecutorService thread.
>>
>> So all we're doing different is authenticating the remote end and if it
>> authenticates permit downloading and classloading.
>>
>> There is one more scenario to consider, currently this is a mechanism to
>> protect against download and deserialization of unknown code for smart
>> proxy's.  But what about Service that only use reflective proxy's and
>> don't require downloaded code?
>>
>> But what if we don't want to grant download permission or class loading
>> permission to a Subject we authenticate?
>>
>> Currently the unmarshalling code doesn't run as the Subject after
>> authentication, this means the Permission grant's are only dependent on
>> authentication, something Michal pointed out earlier when this was
>> proposed.
>>
>> Now this code can be easily changed so the granting permission operation
>> is run as the Subject after authentication, this would allow us to
>> distinguish between different Subjects.
>>
>> The drawback is that performance won't be as good, but it seems the most
>> logical and powerful approach.
>>
>> What do you think?
>>
>> There is one last obstacle, if Certificates are used to sign the jar
>> files, how do you effectively prevent one Subject from using another
>> Subject's signed CodeSource's if Code signing is used for isolation of
>> separate Subjects namespaces?  A service could deliberately attempt to
>> occupy the same namespace as another Service to attempt to gain
>> information via shared static variables.  We need to prevent this
>> occurring.
>>
>> This has to be done with the ClassLoader, but during unmarshalling, the
>> service proxy has not yet been verified.  The authentication proxy
>> delivered with the MarshalInputStream may not have the same Subject as
>> the Service, it could be a third party.
>>
>> Could it be that when the smart proxy is unmarshalled, and executed as
>> it's Subject, it must contain a Certificate matching the signer of the
>> Codebase?
>>
>> We're on the cusp of solving this problem, thoughts?
>>
>> Cheers,
>>
>> Peter.
>>
>> Peter Firmstone (JIRA) wrote:
>>     
>>> Denial of Service during unmarshalling of smart proxy's
>>> -------------------------------------------------------
>>>
>>>                  Key: RIVER-362
>>>                  URL: https://issues.apache.org/jira/browse/RIVER-362
>>>              
>>>              Project: River
>>>           
>>>           Issue Type: Bug
>>>          
>>>          Environment: Untrusted networks
>>>          
>>>             Reporter: Peter Firmstone
>>>
>>> During unmarshalling of smart proxy's there's a period before the proxy
>>> has been verified (authenticated) where deserialization methods are
>>> executed on untrusted code, the potential exists for untrusted code to
>>> perform denial of service.
>>>       


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Michal Kleczek wrote:
> Thanks for taking time to look at this.
>
> 1. I am open to _any_ refactoring (and changing the code completely) - my code 
> is just a prototype. BTW - would it be possible to put it somewhere in SVN? 

I'll create a place in skunk for you, probably won't  be until the 
weekend though.

> It 
> would be much easier for me to contribute - I don't need a commit access - 
> just a simple way to produce patches. (The version attached to JIRA needs 
> patching badly since it does not work :) )
>
> 2. I am not sure I understand the compatibility issues. I assume we're talking 
> about a scenario where there is a running service that has MarshalledInstance 
> objects saved somewhere and we want to upgrade it?
>   

Sort of I mean if there's an Registrar using the old version of 
MarshalledInstance,  clients with new versions will be able to 
deserialize MarshalledInstance, but not it's contained object, because 
the stream implementations are different.  Actually I suspect it may be 
able to resolve the class locally, using only the object byte array, not 
too sure, haven't tested it, based on reading the code.

Clients using the earlier version of MarshalledInstance trying to access 
a Registrar that uses a later version wouldn't be able to discover it's 
proxy.

Reggie's proxy could use Preferred ClassLoading to allow the client to 
use services utilising later versions of MarshalledInstance..

> I think it can be easily solved by making ModuleAnnotatedInputStream capable 
> of reading both String and Module annotations. 

I had some thoughts about making a boot Module part of the serialized 
from of MarshalledInstance, where earlier clients can fall back on the 
String annotation.  Later versions ignore the string annotation if a 
boot Module is present.

> String annotations could be 
> translated to DefaultRmiModule instances installed and used as usual later on.
> I would even say that my version of RMIClassLoaderSpi should be changed so 
> that it can handle both serialized and encoded Modules as well as old style 
> String annotations (lists of URLs). It should also produce old style 
> annotations for DefaultRmiModules - otherwise tools such as VisualVM are not 
> going to work ( tested this :) )
>
> 3. I found the following code in River dependent on annotations being Strings 
> (and RMIClassLoader as well):
> 1) Anything that makes use of MarshalledObject (for example DiscoveryV1, 
> RemoteEventListener)
> 2) Reggie entries assume annotation is a string
> 3) Outrigger - I don't know the details - just checked it calls 
> RMIClassLoader.getClassAnnotation()
> 4) ProxyTrustVerifier - does a check if a candidate proxy's ClassLoader is a 
> proper RMI ClassLoader by comparing annotations produced by RMIClassLoader
>
> Looks to me it is not straightforward to remove River dependency on 
> RMIClassLoader (and - to be honest - it was not my goal at all - I wanted to 
> have a piece of code that would plug into existing River)
>   

Gregg Wonderly provided an implementation, it reportedly worked quite 
well, I've yet to reinstate it and run some tests, but it did pass a 
significant number of tests, I'm waiting for trunk to stabilise, then 
I'll play with it again.
> 4. We can easily support scenarios where a client uses old services (the ones 
> not aware of Modules) - see p. 2. But I don't thing there is an easy way for a 
> service that annotates it's objects with Modules to provide a way for an old 
> client to use it.
>   
See suggestion above.

> 5. Didn't thing too much about implementing all this as a URL handler - it 
> looks pretty complicated to me - handling Manifest classpaths, multi URL 
> codebases etc.
>   

Ok, just thought I'd ask the question.

> 6. Placing constraints on Modules is certainly possible but I have no idea how 
> useful it could be and how hard it would be to implement it.
> The only constraint on a Module we need right now (so that the functionality 
> is on-pair with existing River) is Integrity.YES. We handle it by just having 
> a boolean argument in Module methods. 

Did have a look at the MarshalledInstance I attached earlier, it 
contains a serialization verifier proxy, it's possible to have it 
authenticate and throw an IOException during deserialization if it's not 
authorized.  It uses MessageDigests to confirm the byte array's haven't 
changed during transit, it also clones the arrays to guard against 
stolen references.  This could utilise client and server constraints for 
privacy, authentication and minimum server principal.

If deserialization of MarshalledInstance, followed by unmarshalling of 
it's contained object is done isolated within an Executor thread that 
handles StackOverflowError's, then we're about as bullet proof as we can 
get.  The attacker will probably look for OS vulnerabilities instead and 
steal a trusted identity.

If a client has an earlier version of MarshalledInstance, it simply 
deserializes it and discards the proxy, but it still works as expected, 
the client just doesn't have the Denial of Service deserialization and 
codebase download attack protection.

> It made implementation easy (since it is 
> similar to what we have in River right now). Also - I've got no idea how to 
> implement other constraints - we would have do something really smart in 
> PreferredClassLoader.
>   

Getting Class loading right is important to avoid class visibility 
problems.  Because the service impl, proxy and client all share the same 
common Service API, if they're all in child classloaders relative to the 
ServiceAPI, then we won't have any classloading issues, since were using 
common superclass and interface methods to communicate between different 
namespaces.

> 7. I am not following on how you could get rid of CachingProxyTrust since you 
> need to verify two objects.
>   

Perhaps I've confused the issue, I'm referring to annotating the module 
repeatedly with every object in the stream, rather than just once within 
the MarshalledInstance serialized form.

Cheers,

Peter.

> Thanks,
> Michal
>
> On Tuesday 02 of November 2010 14:52:57 Peter Firmstone wrote:
>   
>> Thanks Michal, that was helpful, sorry for taking so long to reply.
>>
>> Having chewed the details, I think now it is safe for me to comment, I'm
>> wondering if your open to some refactoring?
>>
>> You've managed to produce a lot of code in a very short time, your
>> productivity is quite impressive and you seem proficient using Secure
>> Jini Services.
>>
>> I've been thinking about your use of objects as annotations, which I
>> readily took to, something that's bothering me is backward
>> compatibility, an Object could be changed to a String, but a String is
>> final and existing implementations are stuck with it. MarshalledInstance
>> is part of the Discovery 2 Protocol, and Reggie, so it's serialized form
>> matters to remote foreign parties.
>>
>> The current way that MarshalledInstance Serialized Form is implemented
>> leaves it open to expansion due to readObject's implementation.  This
>> means we can add fields without breaking backward compatibility.  The
>> earlier implementations can utilise the existing fields and drop any
>> superfluous objects they don't know about.
>>
>> I'm wondering if it's possible to implement a Module URL scheme, similar
>> to Codebase Services?
>>
>> I've also wondered if using an authenticating verifier proxy during
>> deserialization of MarshalledInstance would be enough, saving the need
>> to Cache using the caching proxy trust verifier.  MarshalledInstance is
>> the point of contact for Discovery and Lookup, if we require
>> authentication and verification, then that might be sufficient for
>> MarshalledInstance.
>>
>> We can utilise your Module annotated streams via Jeri, unbeknown to
>> external implementations.
>>
>> I've attached a very rough example draft rudimentary untested
>> MarshalledInstance (TODO: server min principal authentication) which
>> uses defensive copying and message digests to confirm the deserialized
>> state as part of the private implementation of MarshalledInstance.  This
>> makes object integrity the responsibility of the Object itself, rather
>> than an external mechanism.  So in this case privacy is the
>> responsibility of external mechanisms, but object integrity is an
>> internal concern.
>>
>> Gregg Wonderly created a CodebaseAnnotationClassloader (I think that's
>> the name I mentioned earlier), this might remove the need to use
>> RMIClassLoaderSPI and provide the opportunity to add some additional
>> functionality.
>>
>> See below for some more comments:
>>
>> Best Regards,
>>
>> Peter.
>>
>> Michal Kleczek wrote:
>>     
>>> On Thursday 28 of October 2010 10:36:38 Peter Firmstone wrote:
>>>       
>>>> Ok Interesting, anyone implementing a Service should be quite capable of
>>>> implementing equals, we should then specify that equals and hashcode
>>>> methods should be implemented for ProxyTrust.
>>>>
>>>> For my benefit can you go over the process of how your new code works?
>>>> I'm interested in the choices you've made & why.
>>>>         
>>> Sure.
>>> Several choices were made because:
>>> 1. I wanted to reuse as much as possible from existing River
>>> 2. I wanted to have a working prototype fast :)
>>>
>>> Anyway:
>>> 1. The main idea is to have annotations as objects that could be verified
>>> using standard River proxy verification facilities. To be honest the
>>> idea of having Module interface that enables plugging different
>>> classloading mechanisms is something completely optional.
>>> 2. For the client the basic scenario is:
>>> a) The client gets a serialized object
>>> b) When it is deserialized annotations (Modules) are read and "installed"
>>> c) Installing a Module means:
>>> c1) checking if it was already installed
>>> c2) if not - prepare it using VerifyingProxyPreparer (I've choosen not to
>>> place any InvocationConstraints on Modules - I don't think it is
>>> necessary)
>>>       
>> I'm curious why client MethodConstraints aren't needed?
>>
>>     
>>> d) after a Module is installed it is used to load classes
>>> 3. There are several places in River that depend on annotations being
>>> Strings provided by RMIClassLoader. The most important places are
>>> a) Discovery
>>> b) Reggie implementation
>>> c) ProxyTrustVerifier
>>> Since I did not want to modify this code I had to implement
>>> RMIClassLoaderSpi so that it would provide serialized Modules as
>>> Strings. I've choosen to simply serialize them to byte arrays and Base64
>>> encode them.
>>> 4. There are two important Module implementations available:
>>> a) DefaultRmiModule
>>> b) ProxyTrustModule
>>> DefaultRmiModule can be trusted by the client without contacting any
>>> service - it uses RequireDlPermissionClassProvider to load classes.
>>> ProxyTrustModule on the other hand uses a simple PreferredClassProvider
>>> to load classes. It is a smart proxy that implements
>>> getProxyTrustIterator() so that it can be verified by
>>> ProxyTrustVerifier.
>>>
>>> On the server before we can annotate our objects with modules we have to
>>> register a Module that will be used as annotation.
>>> If the server does not register any Module - DefaultRmiModule is going to
>>> be used as annotation.
>>> The server can register a ProxyTrustModule as annotation - to do that it
>>> first must export an object that can be contacted to obtain a Module
>>> verifier. In other words - a service must either:
>>> a) export two ProxyTrusts (one for Modules and another one for the
>>> service itself)
>>> b) its ProxyTrust must provide a verifier that is able to verify both a
>>> Module and a service proxy
>>>
>>> To make it possible to use my code with existing services without
>>> modifying them I've decided to implement a special ModuleExporter which
>>> will override the service ServerProxyTrust implementation so that
>>> getProxyVerifier will return a Verifier capable of verifying both a
>>> Module and the service proxy. This verifier works as follows:
>>> 1. Check if an object being verified is a Module.
>>> 2. If so - delegate to a module verifier
>>> 3. If not it means we're verifying a service proxy so delegate to a
>>> default verifier.
>>> The problem is though that when this verifier is deserialized the module
>>> that is capable of loading the service proxy verifier is not yet
>>> installed (the client got this verifier to verify a Module before it can
>>> load any classes). That's why I called it LazyCompositeVerifier - the
>>> default verifier is not deserialized until it is actually needed.
>>>
>>> The only problem left is that every time a client gets a service proxy it
>>> will issue a remote call twice to get a verifier: first to get a
>>> verifier for a Module and then to get a verifier for a service proxy.
>>> But it is going to be the same verifier!!! So I've decided to implement
>>> a CachingProxyTrust that 1) can be trusted by the client without the
>>> need to issue any remote call (so we need a CachingProxyTrustVerifier
>>> configured on the client)
>>> 2) Will cache a verifier it obtains from its delegate
>>>
>>> The problem with CachingProxyTrust is that it has to be used by:
>>> a) a Module
>>> b) a service proxy
>>> That's why we need OverrideProxy - it is returned from ModuleExporter to
>>> the service so that the service is unaware of the CachingProxyTrust but
>>> still can use it to obtain its verifier. To trust OverrideProxy the
>>> client has to have OverrideProxyVerifier configured locally.
>>>
>>> I hope I clarified everything a little bit...
>>>
>>> Michal
>>>       
>
>   


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Hi Michal,

Your code's included in svn at:

https://svn.apache.org/repos/asf/incubator/river/jtsk/skunk/river-modules

If you upload patches to Jira, I'll add them for you.

Cheers,

Peter.

Michal Kleczek wrote:
> Thanks for taking time to look at this.
>
> 1. I am open to _any_ refactoring (and changing the code completely) - my code 
> is just a prototype. BTW - would it be possible to put it somewhere in SVN? It 
> would be much easier for me to contribute - I don't need a commit access - 
> just a simple way to produce patches. (The version attached to JIRA needs 
> patching badly since it does not work :) )
>
> 2. I am not sure I understand the compatibility issues. I assume we're talking 
> about a scenario where there is a running service that has MarshalledInstance 
> objects saved somewhere and we want to upgrade it?
> I think it can be easily solved by making ModuleAnnotatedInputStream capable 
> of reading both String and Module annotations. String annotations could be 
> translated to DefaultRmiModule instances installed and used as usual later on.
> I would even say that my version of RMIClassLoaderSpi should be changed so 
> that it can handle both serialized and encoded Modules as well as old style 
> String annotations (lists of URLs). It should also produce old style 
> annotations for DefaultRmiModules - otherwise tools such as VisualVM are not 
> going to work ( tested this :) )
>
> 3. I found the following code in River dependent on annotations being Strings 
> (and RMIClassLoader as well):
> 1) Anything that makes use of MarshalledObject (for example DiscoveryV1, 
> RemoteEventListener)
> 2) Reggie entries assume annotation is a string
> 3) Outrigger - I don't know the details - just checked it calls 
> RMIClassLoader.getClassAnnotation()
> 4) ProxyTrustVerifier - does a check if a candidate proxy's ClassLoader is a 
> proper RMI ClassLoader by comparing annotations produced by RMIClassLoader
>
> Looks to me it is not straightforward to remove River dependency on 
> RMIClassLoader (and - to be honest - it was not my goal at all - I wanted to 
> have a piece of code that would plug into existing River)
>
> 4. We can easily support scenarios where a client uses old services (the ones 
> not aware of Modules) - see p. 2. But I don't thing there is an easy way for a 
> service that annotates it's objects with Modules to provide a way for an old 
> client to use it.
>
> 5. Didn't thing too much about implementing all this as a URL handler - it 
> looks pretty complicated to me - handling Manifest classpaths, multi URL 
> codebases etc.
>
> 6. Placing constraints on Modules is certainly possible but I have no idea how 
> useful it could be and how hard it would be to implement it.
> The only constraint on a Module we need right now (so that the functionality 
> is on-pair with existing River) is Integrity.YES. We handle it by just having 
> a boolean argument in Module methods. It made implementation easy (since it is 
> similar to what we have in River right now). Also - I've got no idea how to 
> implement other constraints - we would have do something really smart in 
> PreferredClassLoader :)
>
> 7. I am not following on how you could get rid of CachingProxyTrust since you 
> need to verify two objects.
>
> Thanks,
> Michal
>
> On Tuesday 02 of November 2010 14:52:57 Peter Firmstone wrote:
>   
>> Thanks Michal, that was helpful, sorry for taking so long to reply.
>>
>> Having chewed the details, I think now it is safe for me to comment, I'm
>> wondering if your open to some refactoring?
>>
>> You've managed to produce a lot of code in a very short time, your
>> productivity is quite impressive and you seem proficient using Secure
>> Jini Services.
>>
>> I've been thinking about your use of objects as annotations, which I
>> readily took to, something that's bothering me is backward
>> compatibility, an Object could be changed to a String, but a String is
>> final and existing implementations are stuck with it. MarshalledInstance
>> is part of the Discovery 2 Protocol, and Reggie, so it's serialized form
>> matters to remote foreign parties.
>>
>> The current way that MarshalledInstance Serialized Form is implemented
>> leaves it open to expansion due to readObject's implementation.  This
>> means we can add fields without breaking backward compatibility.  The
>> earlier implementations can utilise the existing fields and drop any
>> superfluous objects they don't know about.
>>
>> I'm wondering if it's possible to implement a Module URL scheme, similar
>> to Codebase Services?
>>
>> I've also wondered if using an authenticating verifier proxy during
>> deserialization of MarshalledInstance would be enough, saving the need
>> to Cache using the caching proxy trust verifier.  MarshalledInstance is
>> the point of contact for Discovery and Lookup, if we require
>> authentication and verification, then that might be sufficient for
>> MarshalledInstance.
>>
>> We can utilise your Module annotated streams via Jeri, unbeknown to
>> external implementations.
>>
>> I've attached a very rough example draft rudimentary untested
>> MarshalledInstance (TODO: server min principal authentication) which
>> uses defensive copying and message digests to confirm the deserialized
>> state as part of the private implementation of MarshalledInstance.  This
>> makes object integrity the responsibility of the Object itself, rather
>> than an external mechanism.  So in this case privacy is the
>> responsibility of external mechanisms, but object integrity is an
>> internal concern.
>>
>> Gregg Wonderly created a CodebaseAnnotationClassloader (I think that's
>> the name I mentioned earlier), this might remove the need to use
>> RMIClassLoaderSPI and provide the opportunity to add some additional
>> functionality.
>>
>> See below for some more comments:
>>
>> Best Regards,
>>
>> Peter.
>>
>> Michal Kleczek wrote:
>>     
>>> On Thursday 28 of October 2010 10:36:38 Peter Firmstone wrote:
>>>       
>>>> Ok Interesting, anyone implementing a Service should be quite capable of
>>>> implementing equals, we should then specify that equals and hashcode
>>>> methods should be implemented for ProxyTrust.
>>>>
>>>> For my benefit can you go over the process of how your new code works?
>>>> I'm interested in the choices you've made & why.
>>>>         
>>> Sure.
>>> Several choices were made because:
>>> 1. I wanted to reuse as much as possible from existing River
>>> 2. I wanted to have a working prototype fast :)
>>>
>>> Anyway:
>>> 1. The main idea is to have annotations as objects that could be verified
>>> using standard River proxy verification facilities. To be honest the
>>> idea of having Module interface that enables plugging different
>>> classloading mechanisms is something completely optional.
>>> 2. For the client the basic scenario is:
>>> a) The client gets a serialized object
>>> b) When it is deserialized annotations (Modules) are read and "installed"
>>> c) Installing a Module means:
>>> c1) checking if it was already installed
>>> c2) if not - prepare it using VerifyingProxyPreparer (I've choosen not to
>>> place any InvocationConstraints on Modules - I don't think it is
>>> necessary)
>>>       
>> I'm curious why client MethodConstraints aren't needed?
>>
>>     
>>> d) after a Module is installed it is used to load classes
>>> 3. There are several places in River that depend on annotations being
>>> Strings provided by RMIClassLoader. The most important places are
>>> a) Discovery
>>> b) Reggie implementation
>>> c) ProxyTrustVerifier
>>> Since I did not want to modify this code I had to implement
>>> RMIClassLoaderSpi so that it would provide serialized Modules as
>>> Strings. I've choosen to simply serialize them to byte arrays and Base64
>>> encode them.
>>> 4. There are two important Module implementations available:
>>> a) DefaultRmiModule
>>> b) ProxyTrustModule
>>> DefaultRmiModule can be trusted by the client without contacting any
>>> service - it uses RequireDlPermissionClassProvider to load classes.
>>> ProxyTrustModule on the other hand uses a simple PreferredClassProvider
>>> to load classes. It is a smart proxy that implements
>>> getProxyTrustIterator() so that it can be verified by
>>> ProxyTrustVerifier.
>>>
>>> On the server before we can annotate our objects with modules we have to
>>> register a Module that will be used as annotation.
>>> If the server does not register any Module - DefaultRmiModule is going to
>>> be used as annotation.
>>> The server can register a ProxyTrustModule as annotation - to do that it
>>> first must export an object that can be contacted to obtain a Module
>>> verifier. In other words - a service must either:
>>> a) export two ProxyTrusts (one for Modules and another one for the
>>> service itself)
>>> b) its ProxyTrust must provide a verifier that is able to verify both a
>>> Module and a service proxy
>>>
>>> To make it possible to use my code with existing services without
>>> modifying them I've decided to implement a special ModuleExporter which
>>> will override the service ServerProxyTrust implementation so that
>>> getProxyVerifier will return a Verifier capable of verifying both a
>>> Module and the service proxy. This verifier works as follows:
>>> 1. Check if an object being verified is a Module.
>>> 2. If so - delegate to a module verifier
>>> 3. If not it means we're verifying a service proxy so delegate to a
>>> default verifier.
>>> The problem is though that when this verifier is deserialized the module
>>> that is capable of loading the service proxy verifier is not yet
>>> installed (the client got this verifier to verify a Module before it can
>>> load any classes). That's why I called it LazyCompositeVerifier - the
>>> default verifier is not deserialized until it is actually needed.
>>>
>>> The only problem left is that every time a client gets a service proxy it
>>> will issue a remote call twice to get a verifier: first to get a
>>> verifier for a Module and then to get a verifier for a service proxy.
>>> But it is going to be the same verifier!!! So I've decided to implement
>>> a CachingProxyTrust that 1) can be trusted by the client without the
>>> need to issue any remote call (so we need a CachingProxyTrustVerifier
>>> configured on the client)
>>> 2) Will cache a verifier it obtains from its delegate
>>>
>>> The problem with CachingProxyTrust is that it has to be used by:
>>> a) a Module
>>> b) a service proxy
>>> That's why we need OverrideProxy - it is returned from ModuleExporter to
>>> the service so that the service is unaware of the CachingProxyTrust but
>>> still can use it to obtain its verifier. To trust OverrideProxy the
>>> client has to have OverrideProxyVerifier configured locally.
>>>
>>> I hope I clarified everything a little bit...
>>>
>>> Michal
>>>       
>
>   


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Michal Kleczek <mi...@xpro.biz>.
Thanks for taking time to look at this.

1. I am open to _any_ refactoring (and changing the code completely) - my code 
is just a prototype. BTW - would it be possible to put it somewhere in SVN? It 
would be much easier for me to contribute - I don't need a commit access - 
just a simple way to produce patches. (The version attached to JIRA needs 
patching badly since it does not work :) )

2. I am not sure I understand the compatibility issues. I assume we're talking 
about a scenario where there is a running service that has MarshalledInstance 
objects saved somewhere and we want to upgrade it?
I think it can be easily solved by making ModuleAnnotatedInputStream capable 
of reading both String and Module annotations. String annotations could be 
translated to DefaultRmiModule instances installed and used as usual later on.
I would even say that my version of RMIClassLoaderSpi should be changed so 
that it can handle both serialized and encoded Modules as well as old style 
String annotations (lists of URLs). It should also produce old style 
annotations for DefaultRmiModules - otherwise tools such as VisualVM are not 
going to work ( tested this :) )

3. I found the following code in River dependent on annotations being Strings 
(and RMIClassLoader as well):
1) Anything that makes use of MarshalledObject (for example DiscoveryV1, 
RemoteEventListener)
2) Reggie entries assume annotation is a string
3) Outrigger - I don't know the details - just checked it calls 
RMIClassLoader.getClassAnnotation()
4) ProxyTrustVerifier - does a check if a candidate proxy's ClassLoader is a 
proper RMI ClassLoader by comparing annotations produced by RMIClassLoader

Looks to me it is not straightforward to remove River dependency on 
RMIClassLoader (and - to be honest - it was not my goal at all - I wanted to 
have a piece of code that would plug into existing River)

4. We can easily support scenarios where a client uses old services (the ones 
not aware of Modules) - see p. 2. But I don't thing there is an easy way for a 
service that annotates it's objects with Modules to provide a way for an old 
client to use it.

5. Didn't thing too much about implementing all this as a URL handler - it 
looks pretty complicated to me - handling Manifest classpaths, multi URL 
codebases etc.

6. Placing constraints on Modules is certainly possible but I have no idea how 
useful it could be and how hard it would be to implement it.
The only constraint on a Module we need right now (so that the functionality 
is on-pair with existing River) is Integrity.YES. We handle it by just having 
a boolean argument in Module methods. It made implementation easy (since it is 
similar to what we have in River right now). Also - I've got no idea how to 
implement other constraints - we would have do something really smart in 
PreferredClassLoader :)

7. I am not following on how you could get rid of CachingProxyTrust since you 
need to verify two objects.

Thanks,
Michal

On Tuesday 02 of November 2010 14:52:57 Peter Firmstone wrote:
> Thanks Michal, that was helpful, sorry for taking so long to reply.
> 
> Having chewed the details, I think now it is safe for me to comment, I'm
> wondering if your open to some refactoring?
> 
> You've managed to produce a lot of code in a very short time, your
> productivity is quite impressive and you seem proficient using Secure
> Jini Services.
> 
> I've been thinking about your use of objects as annotations, which I
> readily took to, something that's bothering me is backward
> compatibility, an Object could be changed to a String, but a String is
> final and existing implementations are stuck with it. MarshalledInstance
> is part of the Discovery 2 Protocol, and Reggie, so it's serialized form
> matters to remote foreign parties.
> 
> The current way that MarshalledInstance Serialized Form is implemented
> leaves it open to expansion due to readObject's implementation.  This
> means we can add fields without breaking backward compatibility.  The
> earlier implementations can utilise the existing fields and drop any
> superfluous objects they don't know about.
> 
> I'm wondering if it's possible to implement a Module URL scheme, similar
> to Codebase Services?
> 
> I've also wondered if using an authenticating verifier proxy during
> deserialization of MarshalledInstance would be enough, saving the need
> to Cache using the caching proxy trust verifier.  MarshalledInstance is
> the point of contact for Discovery and Lookup, if we require
> authentication and verification, then that might be sufficient for
> MarshalledInstance.
> 
> We can utilise your Module annotated streams via Jeri, unbeknown to
> external implementations.
> 
> I've attached a very rough example draft rudimentary untested
> MarshalledInstance (TODO: server min principal authentication) which
> uses defensive copying and message digests to confirm the deserialized
> state as part of the private implementation of MarshalledInstance.  This
> makes object integrity the responsibility of the Object itself, rather
> than an external mechanism.  So in this case privacy is the
> responsibility of external mechanisms, but object integrity is an
> internal concern.
> 
> Gregg Wonderly created a CodebaseAnnotationClassloader (I think that's
> the name I mentioned earlier), this might remove the need to use
> RMIClassLoaderSPI and provide the opportunity to add some additional
> functionality.
> 
> See below for some more comments:
> 
> Best Regards,
> 
> Peter.
> 
> Michal Kleczek wrote:
> > On Thursday 28 of October 2010 10:36:38 Peter Firmstone wrote:
> >> Ok Interesting, anyone implementing a Service should be quite capable of
> >> implementing equals, we should then specify that equals and hashcode
> >> methods should be implemented for ProxyTrust.
> >> 
> >> For my benefit can you go over the process of how your new code works?
> >> I'm interested in the choices you've made & why.
> > 
> > Sure.
> > Several choices were made because:
> > 1. I wanted to reuse as much as possible from existing River
> > 2. I wanted to have a working prototype fast :)
> > 
> > Anyway:
> > 1. The main idea is to have annotations as objects that could be verified
> > using standard River proxy verification facilities. To be honest the
> > idea of having Module interface that enables plugging different
> > classloading mechanisms is something completely optional.
> > 2. For the client the basic scenario is:
> > a) The client gets a serialized object
> > b) When it is deserialized annotations (Modules) are read and "installed"
> > c) Installing a Module means:
> > c1) checking if it was already installed
> > c2) if not - prepare it using VerifyingProxyPreparer (I've choosen not to
> > place any InvocationConstraints on Modules - I don't think it is
> > necessary)
> 
> I'm curious why client MethodConstraints aren't needed?
> 
> > d) after a Module is installed it is used to load classes
> > 3. There are several places in River that depend on annotations being
> > Strings provided by RMIClassLoader. The most important places are
> > a) Discovery
> > b) Reggie implementation
> > c) ProxyTrustVerifier
> > Since I did not want to modify this code I had to implement
> > RMIClassLoaderSpi so that it would provide serialized Modules as
> > Strings. I've choosen to simply serialize them to byte arrays and Base64
> > encode them.
> > 4. There are two important Module implementations available:
> > a) DefaultRmiModule
> > b) ProxyTrustModule
> > DefaultRmiModule can be trusted by the client without contacting any
> > service - it uses RequireDlPermissionClassProvider to load classes.
> > ProxyTrustModule on the other hand uses a simple PreferredClassProvider
> > to load classes. It is a smart proxy that implements
> > getProxyTrustIterator() so that it can be verified by
> > ProxyTrustVerifier.
> > 
> > On the server before we can annotate our objects with modules we have to
> > register a Module that will be used as annotation.
> > If the server does not register any Module - DefaultRmiModule is going to
> > be used as annotation.
> > The server can register a ProxyTrustModule as annotation - to do that it
> > first must export an object that can be contacted to obtain a Module
> > verifier. In other words - a service must either:
> > a) export two ProxyTrusts (one for Modules and another one for the
> > service itself)
> > b) its ProxyTrust must provide a verifier that is able to verify both a
> > Module and a service proxy
> > 
> > To make it possible to use my code with existing services without
> > modifying them I've decided to implement a special ModuleExporter which
> > will override the service ServerProxyTrust implementation so that
> > getProxyVerifier will return a Verifier capable of verifying both a
> > Module and the service proxy. This verifier works as follows:
> > 1. Check if an object being verified is a Module.
> > 2. If so - delegate to a module verifier
> > 3. If not it means we're verifying a service proxy so delegate to a
> > default verifier.
> > The problem is though that when this verifier is deserialized the module
> > that is capable of loading the service proxy verifier is not yet
> > installed (the client got this verifier to verify a Module before it can
> > load any classes). That's why I called it LazyCompositeVerifier - the
> > default verifier is not deserialized until it is actually needed.
> > 
> > The only problem left is that every time a client gets a service proxy it
> > will issue a remote call twice to get a verifier: first to get a
> > verifier for a Module and then to get a verifier for a service proxy.
> > But it is going to be the same verifier!!! So I've decided to implement
> > a CachingProxyTrust that 1) can be trusted by the client without the
> > need to issue any remote call (so we need a CachingProxyTrustVerifier
> > configured on the client)
> > 2) Will cache a verifier it obtains from its delegate
> > 
> > The problem with CachingProxyTrust is that it has to be used by:
> > a) a Module
> > b) a service proxy
> > That's why we need OverrideProxy - it is returned from ModuleExporter to
> > the service so that the service is unaware of the CachingProxyTrust but
> > still can use it to obtain its verifier. To trust OverrideProxy the
> > client has to have OverrideProxyVerifier configured locally.
> > 
> > I hope I clarified everything a little bit...
> > 
> > Michal

Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Thanks Michal, that was helpful, sorry for taking so long to reply.

Having chewed the details, I think now it is safe for me to comment, I'm 
wondering if your open to some refactoring?

You've managed to produce a lot of code in a very short time, your 
productivity is quite impressive and you seem proficient using Secure 
Jini Services.

I've been thinking about your use of objects as annotations, which I 
readily took to, something that's bothering me is backward 
compatibility, an Object could be changed to a String, but a String is 
final and existing implementations are stuck with it. MarshalledInstance 
is part of the Discovery 2 Protocol, and Reggie, so it's serialized form 
matters to remote foreign parties.

The current way that MarshalledInstance Serialized Form is implemented 
leaves it open to expansion due to readObject's implementation.  This 
means we can add fields without breaking backward compatibility.  The 
earlier implementations can utilise the existing fields and drop any 
superfluous objects they don't know about.

I'm wondering if it's possible to implement a Module URL scheme, similar 
to Codebase Services?

I've also wondered if using an authenticating verifier proxy during 
deserialization of MarshalledInstance would be enough, saving the need 
to Cache using the caching proxy trust verifier.  MarshalledInstance is 
the point of contact for Discovery and Lookup, if we require 
authentication and verification, then that might be sufficient for 
MarshalledInstance. 

We can utilise your Module annotated streams via Jeri, unbeknown to 
external implementations. 

I've attached a very rough example draft rudimentary untested 
MarshalledInstance (TODO: server min principal authentication) which 
uses defensive copying and message digests to confirm the deserialized 
state as part of the private implementation of MarshalledInstance.  This 
makes object integrity the responsibility of the Object itself, rather 
than an external mechanism.  So in this case privacy is the 
responsibility of external mechanisms, but object integrity is an 
internal concern.

Gregg Wonderly created a CodebaseAnnotationClassloader (I think that's 
the name I mentioned earlier), this might remove the need to use 
RMIClassLoaderSPI and provide the opportunity to add some additional 
functionality.

See below for some more comments:

Best Regards,

Peter.

Michal Kleczek wrote:
> On Thursday 28 of October 2010 10:36:38 Peter Firmstone wrote:
>   
>> Ok Interesting, anyone implementing a Service should be quite capable of
>> implementing equals, we should then specify that equals and hashcode
>> methods should be implemented for ProxyTrust.
>>
>> For my benefit can you go over the process of how your new code works?
>> I'm interested in the choices you've made & why.
>>
>>     
>
> Sure.
> Several choices were made because:
> 1. I wanted to reuse as much as possible from existing River
> 2. I wanted to have a working prototype fast :)
>
> Anyway:
> 1. The main idea is to have annotations as objects that could be verified using 
> standard River proxy verification facilities. To be honest the idea of having 
> Module interface that enables plugging different classloading mechanisms is 
> something completely optional.
> 2. For the client the basic scenario is:
> a) The client gets a serialized object
> b) When it is deserialized annotations (Modules) are read and "installed"
> c) Installing a Module means:
> c1) checking if it was already installed
> c2) if not - prepare it using VerifyingProxyPreparer (I've choosen not to 
> place any InvocationConstraints on Modules - I don't think it is necessary)
>   

I'm curious why client MethodConstraints aren't needed?

> d) after a Module is installed it is used to load classes
> 3. There are several places in River that depend on annotations being Strings 
> provided by RMIClassLoader. The most important places are
> a) Discovery
> b) Reggie implementation
> c) ProxyTrustVerifier
> Since I did not want to modify this code I had to implement RMIClassLoaderSpi 
> so that it would provide serialized Modules as Strings. I've choosen to simply 
> serialize them to byte arrays and Base64 encode them.
> 4. There are two important Module implementations available:
> a) DefaultRmiModule
> b) ProxyTrustModule
> DefaultRmiModule can be trusted by the client without contacting any service - 
> it uses RequireDlPermissionClassProvider to load classes.
> ProxyTrustModule on the other hand uses a simple PreferredClassProvider to 
> load classes. It is a smart proxy that implements getProxyTrustIterator() so 
> that it can be verified by ProxyTrustVerifier.
>
> On the server before we can annotate our objects with modules we have to 
> register a Module that will be used as annotation.
> If the server does not register any Module - DefaultRmiModule is going to be 
> used as annotation.
> The server can register a ProxyTrustModule as annotation - to do that it first 
> must export an object that can be contacted to obtain a Module verifier.
> In other words - a service must either:
> a) export two ProxyTrusts (one for Modules and another one for the service 
> itself)
> b) its ProxyTrust must provide a verifier that is able to verify both a Module 
> and a service proxy
>
> To make it possible to use my code with existing services without modifying 
> them I've decided to implement a special ModuleExporter which will override 
> the service ServerProxyTrust implementation so that getProxyVerifier will 
> return a Verifier capable of verifying both a Module and the service proxy.
> This verifier works as follows:
> 1. Check if an object being verified is a Module.
> 2. If so - delegate to a module verifier
> 3. If not it means we're verifying a service proxy so delegate to a default 
> verifier.
> The problem is though that when this verifier is deserialized the module that 
> is capable of loading the service proxy verifier is not yet installed (the 
> client got this verifier to verify a Module before it can load any classes). 
> That's why I called it LazyCompositeVerifier - the default verifier is not 
> deserialized until it is actually needed.
>
> The only problem left is that every time a client gets a service proxy it will 
> issue a remote call twice to get a verifier: first to get a verifier for a Module 
> and then to get a verifier for a service proxy. But it is going to be the same 
> verifier!!! So I've decided to implement a CachingProxyTrust that
> 1) can be trusted by the client without the need to issue any remote call (so 
> we need a CachingProxyTrustVerifier configured on the client)
> 2) Will cache a verifier it obtains from its delegate
>
> The problem with CachingProxyTrust is that it has to be used by:
> a) a Module
> b) a service proxy
> That's why we need OverrideProxy - it is returned from ModuleExporter to the 
> service so that the service is unaware of the CachingProxyTrust but still can 
> use it to obtain its verifier. To trust OverrideProxy the client has to have 
> OverrideProxyVerifier configured locally.
>
> I hope I clarified everything a little bit...
>
> Michal
>
>   




Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Michal Kleczek <mi...@xpro.biz>.
On Thursday 28 of October 2010 10:36:38 Peter Firmstone wrote:
> Ok Interesting, anyone implementing a Service should be quite capable of
> implementing equals, we should then specify that equals and hashcode
> methods should be implemented for ProxyTrust.
> 
> For my benefit can you go over the process of how your new code works?
> I'm interested in the choices you've made & why.
> 

Sure.
Several choices were made because:
1. I wanted to reuse as much as possible from existing River
2. I wanted to have a working prototype fast :)

Anyway:
1. The main idea is to have annotations as objects that could be verified using 
standard River proxy verification facilities. To be honest the idea of having 
Module interface that enables plugging different classloading mechanisms is 
something completely optional.
2. For the client the basic scenario is:
a) The client gets a serialized object
b) When it is deserialized annotations (Modules) are read and "installed"
c) Installing a Module means:
c1) checking if it was already installed
c2) if not - prepare it using VerifyingProxyPreparer (I've choosen not to 
place any InvocationConstraints on Modules - I don't think it is necessary)
d) after a Module is installed it is used to load classes
3. There are several places in River that depend on annotations being Strings 
provided by RMIClassLoader. The most important places are
a) Discovery
b) Reggie implementation
c) ProxyTrustVerifier
Since I did not want to modify this code I had to implement RMIClassLoaderSpi 
so that it would provide serialized Modules as Strings. I've choosen to simply 
serialize them to byte arrays and Base64 encode them.
4. There are two important Module implementations available:
a) DefaultRmiModule
b) ProxyTrustModule
DefaultRmiModule can be trusted by the client without contacting any service - 
it uses RequireDlPermissionClassProvider to load classes.
ProxyTrustModule on the other hand uses a simple PreferredClassProvider to 
load classes. It is a smart proxy that implements getProxyTrustIterator() so 
that it can be verified by ProxyTrustVerifier.

On the server before we can annotate our objects with modules we have to 
register a Module that will be used as annotation.
If the server does not register any Module - DefaultRmiModule is going to be 
used as annotation.
The server can register a ProxyTrustModule as annotation - to do that it first 
must export an object that can be contacted to obtain a Module verifier.
In other words - a service must either:
a) export two ProxyTrusts (one for Modules and another one for the service 
itself)
b) its ProxyTrust must provide a verifier that is able to verify both a Module 
and a service proxy

To make it possible to use my code with existing services without modifying 
them I've decided to implement a special ModuleExporter which will override 
the service ServerProxyTrust implementation so that getProxyVerifier will 
return a Verifier capable of verifying both a Module and the service proxy.
This verifier works as follows:
1. Check if an object being verified is a Module.
2. If so - delegate to a module verifier
3. If not it means we're verifying a service proxy so delegate to a default 
verifier.
The problem is though that when this verifier is deserialized the module that 
is capable of loading the service proxy verifier is not yet installed (the 
client got this verifier to verify a Module before it can load any classes). 
That's why I called it LazyCompositeVerifier - the default verifier is not 
deserialized until it is actually needed.

The only problem left is that every time a client gets a service proxy it will 
issue a remote call twice to get a verifier: first to get a verifier for a Module 
and then to get a verifier for a service proxy. But it is going to be the same 
verifier!!! So I've decided to implement a CachingProxyTrust that
1) can be trusted by the client without the need to issue any remote call (so 
we need a CachingProxyTrustVerifier configured on the client)
2) Will cache a verifier it obtains from its delegate

The problem with CachingProxyTrust is that it has to be used by:
a) a Module
b) a service proxy
That's why we need OverrideProxy - it is returned from ModuleExporter to the 
service so that the service is unaware of the CachingProxyTrust but still can 
use it to obtain its verifier. To trust OverrideProxy the client has to have 
OverrideProxyVerifier configured locally.

I hope I clarified everything a little bit...

Michal

Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Michal Kleczek wrote:
> On Tuesday 26 of October 2010 15:27:17 Peter Firmstone wrote:
>   
>> Hi Michal,
>>
>> Sorry for taking time to respond, I've been busy and am still digesting
>> the code.
>>
>> Michal Kleczek wrote:
>>     
>>> In my code there is a simple hack to force creating a different
>>> ClassLoader for each unique Module - before calling to a delegate
>>> RMIClassProviderSpi I set a TCCL to a new ClassLoader that is unique to
>>> the Module. (That is also the reason I had to provide a slightly
>>> modified version of BasicJeriTrustVerifier so that not the proxy
>>> ClassLoader but also its parent are verified) See AbstractRmiModule for
>>> details.
>>>
>>> Module uniqueness: two Modules are considered the same iff their equals
>>> returns true.
>>>
>>> In case of ProxyTrustModule (which is the most interesting) - two
>>> ProxyTrustModules are equal when their codebases are equal and their
>>> ProxyTrusts are equal. so for two different services - each providing its
>>> own ProxyTrust for Modules - we create two different ClassLoaders
>>> regardless of the codebases. (This is not based on Subject but on
>>> service proxy identity) Basing it on Subject would be a little tricky
>>> IMHO because actual service Principals are dependent on what the client
>>> requires.
>>>       
>> Ok I see your point, we should be using service proxy identity, not the
>> Subject.  A server might use a number of subjects. Since not all proxy's
>> are services, would it be better to use the BasicObjectEndpoint identity.
>>
>> ProxyTrust, doesn't by default implement equals or hashcode, if the
>> client is handed a reference to a remote object, that is a smart proxy,
>> from another client, it could end up with two separate instances if
>> ProxyTrust uses the default Object equals implementation.
>>
>> So thinking about it a little more, perhaps we could use the Uuid of the
>> BasicObjectEndpoint?
>>     
>
> Hmm... I've checked BasicInvoationHandler and it implements equals for its 
> proxies by (among other stuff) comparing object endpoints.
> So in basic scenario (when ProxyTrust is a simple Jeri proxy) all is fine.
> For smart proxies I would simply require "sensible" implementation of equals. 
>
> It is in the interest of a service to provide a client with the right Module 
> identity - otherwise the service just won't work properly (but it will not 
> affect client's security). Equals for me seems to be the easiest and general 
> enough. I wouldn't want to base it on some internal stuff since that would 
> preclude Modules that are not Jeri based etc...
>
> Michal
>
>   
Ok Interesting, anyone implementing a Service should be quite capable of 
implementing equals, we should then specify that equals and hashcode 
methods should be implemented for ProxyTrust.

For my benefit can you go over the process of how your new code works?  
I'm interested in the choices you've made & why.

I still would like to wrap the ClassLoader in a GuardObject, this way 
less trusted code (you don't want it to see the ClassLoader) cannot 
obtain a ClassLoader reference, but it can delegate the functionality by 
passing the GuardObject to more trusted code.

A little off topic, but based on what we can do if we solve the DOS 
problem. I was just thinking today that we could create an Internet 
Service Browser, that discovered any service available over the 
internet, utilising ServiceUI, with which users can interact.  Just like 
Web servers and Web browsers, a River Service browser, wouldn't need to 
implement service (unless it advertised trusted services perhaps), it 
could be a lightweight app for minimal download.  It would be the web 
browser for services.  This could be done using DNS-SD to discover 
Unicast addresses of Lookup services.  This would render the app store 
model obsolete, anyone could advertise their service applications with 
their own lookup service.  It would blur the lines between applications 
and internet web sites.  We would also need delayed unmarshalling of 
proxy's or partial unmarshalling (only deserialize Entry's) until the 
desired service is found.

I'm wondering how we could use PGP Certificates web of trust and utilise 
JAAS to associate with local Principals?  Would these local Principals 
have standard names, representing levels of trust?  For maximum trust 
you would expect the Service to authenticate with all these Principals.

How could we authenticate the Service with these principals?

If a friend trusts and uses a service, can we use and trust that service 
too? Might that trust be the number of Principals our friends 
authenticates the service with? Or would we use a lesser trust? Could 
this be a role of an extended lookup service, to find services that have 
some kind of trust relationship?  Or would it be some kind of trust service?

If we can spell out these trust levels, then the service implementer 
knows which Principals are needed to gain certain permissions.  These 
principal based permission grants could be configured by default in the 
client.

Services might also expect clients to authenticate with these services.  
Any ideas?

Thanks,

Peter.



Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Michal Kleczek <mi...@xpro.biz>.
On Tuesday 26 of October 2010 15:27:17 Peter Firmstone wrote:
> Hi Michal,
> 
> Sorry for taking time to respond, I've been busy and am still digesting
> the code.
> 
> Michal Kleczek wrote:
> > In my code there is a simple hack to force creating a different
> > ClassLoader for each unique Module - before calling to a delegate
> > RMIClassProviderSpi I set a TCCL to a new ClassLoader that is unique to
> > the Module. (That is also the reason I had to provide a slightly
> > modified version of BasicJeriTrustVerifier so that not the proxy
> > ClassLoader but also its parent are verified) See AbstractRmiModule for
> > details.
> > 
> > Module uniqueness: two Modules are considered the same iff their equals
> > returns true.
> > 
> > In case of ProxyTrustModule (which is the most interesting) - two
> > ProxyTrustModules are equal when their codebases are equal and their
> > ProxyTrusts are equal. so for two different services - each providing its
> > own ProxyTrust for Modules - we create two different ClassLoaders
> > regardless of the codebases. (This is not based on Subject but on
> > service proxy identity) Basing it on Subject would be a little tricky
> > IMHO because actual service Principals are dependent on what the client
> > requires.
> 
> Ok I see your point, we should be using service proxy identity, not the
> Subject.  A server might use a number of subjects. Since not all proxy's
> are services, would it be better to use the BasicObjectEndpoint identity.
> 
> ProxyTrust, doesn't by default implement equals or hashcode, if the
> client is handed a reference to a remote object, that is a smart proxy,
> from another client, it could end up with two separate instances if
> ProxyTrust uses the default Object equals implementation.
> 
> So thinking about it a little more, perhaps we could use the Uuid of the
> BasicObjectEndpoint?

Hmm... I've checked BasicInvoationHandler and it implements equals for its 
proxies by (among other stuff) comparing object endpoints.
So in basic scenario (when ProxyTrust is a simple Jeri proxy) all is fine.
For smart proxies I would simply require "sensible" implementation of equals. 

It is in the interest of a service to provide a client with the right Module 
identity - otherwise the service just won't work properly (but it will not 
affect client's security). Equals for me seems to be the easiest and general 
enough. I wouldn't want to base it on some internal stuff since that would 
preclude Modules that are not Jeri based etc...

Michal

Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Michal Kleczek <mi...@xpro.biz>.
Changed package names to org.apache.river.modules.
Added Apache licence headers to source files (BTW - found a pretty cool Maven 
plugin to do it).
Attached zipped source to Jira item.

Regards,
Michal

On Tuesday 19 of October 2010 10:13:27 Peter Firmstone wrote:
> Michal Kleczek wrote:
> > I will.
> > Just let me know if I should change package names, add licence note to
> > source files etc.
> 
> Yes add the apache license header to each file.
> 
> > And what is the policy of using external libraries. This code uses:
> > 1. commons-codec - which is Apache project
> > 2. Google Code Guava (formerly Google Collections) - which is not Apache
> > but its licence is Apache Licence
> 
> We can distribute the binary lib jar's in these cases.
> 
> > Regards,
> > Michal
> > 
> > On Tuesday 19 of October 2010 09:44:14 Peter Firmstone wrote:
> >> Hi Michal,
> >> 
> >> If you upload the code to Jira, I'll create a place on svn where we can
> >> all explore & contribute patches etc.
> >> 
> >> Cheers,
> >> 
> >> Peter.

Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Michal Kleczek wrote:
> I will.
> Just let me know if I should change package names, add licence note to source 
> files etc.
>   

Yes add the apache license header to each file.

> And what is the policy of using external libraries. This code uses:
> 1. commons-codec - which is Apache project
> 2. Google Code Guava (formerly Google Collections) - which is not Apache but 
> its licence is Apache Licence
>   

We can distribute the binary lib jar's in these cases. 

> Regards,
> Michal
>
> On Tuesday 19 of October 2010 09:44:14 Peter Firmstone wrote:
>   
>> Hi Michal,
>>
>> If you upload the code to Jira, I'll create a place on svn where we can
>> all explore & contribute patches etc.
>>
>> Cheers,
>>
>> Peter.
>>
>>     
>
>   


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Michal Kleczek <mi...@xpro.biz>.
I will.
Just let me know if I should change package names, add licence note to source 
files etc.
And what is the policy of using external libraries. This code uses:
1. commons-codec - which is Apache project
2. Google Code Guava (formerly Google Collections) - which is not Apache but 
its licence is Apache Licence

Regards,
Michal

On Tuesday 19 of October 2010 09:44:14 Peter Firmstone wrote:
> Hi Michal,
> 
> If you upload the code to Jira, I'll create a place on svn where we can
> all explore & contribute patches etc.
> 
> Cheers,
> 
> Peter.
> 

Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Hi Michal,

If you upload the code to Jira, I'll create a place on svn where we can 
all explore & contribute patches etc.

Cheers,

Peter.

Michal Kleczek wrote:
> In my code there is a simple hack to force creating a different ClassLoader for 
> each unique Module - before calling to a delegate RMIClassProviderSpi I set a 
> TCCL to a new ClassLoader that is unique to the Module. (That is also the 
> reason I had to provide a slightly modified version of BasicJeriTrustVerifier so 
> that not the proxy ClassLoader but also its parent are verified)
> See AbstractRmiModule for details.
>
> Module uniqueness: two Modules are considered the same iff their equals returns 
> true.
>
> In case of ProxyTrustModule (which is the most interesting) - two 
> ProxyTrustModules are equal when their codebases are equal and their 
> ProxyTrusts are equal. so for two different services - each providing its own 
> ProxyTrust for Modules - we create two different ClassLoaders regardless of the 
> codebases. (This is not based on Subject but on service proxy identity)
> Basing it on Subject would be a little tricky IMHO because actual service 
> Principals are dependent on what the client requires.
>
> We can sign codebases using SignedRmiModule which - beside codebase - carries 
> signature information with it and can be verified locally by 
> SignedRmiModuleVerifier (not yet finished). I also thought about delegating 
> signature verification work to a (remote) service that would be carried by 
> SignedRmiModule and verified for trust before used by the client to verify the 
> actual signature.
>
> The whole design was based on Jini 2.1 so no dynamic CodeBase grants are 
> necessary.
>
> Regards,
> Michal
>
> On Tuesday 19 of October 2010 03:10:50 Peter Firmstone wrote:
>   
>> Michal,
>>
>> You compose an incredible amount of code in a very short time, I haven't
>> yet digested it.
>>
>> I'm still trying to figure out how a Service proxy's namespace can be
>> restricted to a single Subject (the Service authenticates itself with).
>>
>> To avoid security vulnerabilities, caused by shared class state.
>>
>> Classes within a ClassLoader belonging to a particular Service should
>> have no visibility outside their ClassLoader, external classes should
>> only be able to interact via Service API, they shouldn't be able to
>> create objects using constructors from within the service proxy's
>> namespace.  The Service proxy needs to have isolated visibility.
>>
>> Objects within the proxy's private namespace are constructed during
>> deserialization.
>>
>> We could require that a proxy codebase must be signed, we could also
>> require that the Subject, when it authenticates has the same Certificate
>> as the codebase.  Since Certificate's have chains of trust, which can
>> grow longer, it would only be the first Certificate in each
>> Certificate[] array (Subject and CodeSource) that would be checked.
>>
>> Using Codebase Certificate's has an advantage over message digests
>> because the implementation can change.
>>
>> After a smart proxy has been unmarshalled, if it is discovered that the
>> Certificates don't match, this indicates the proxy has been downloaded
>> into the wrong namespace, this proxy can be safely discarded.
>>
>> Cheers,
>>
>> Peter.
>>
>> Michal Kleczek wrote:
>>     
>>> Folks,
>>>
>>> I've managed to create a prototype implementation of the idea of
>>> annotating classes with Modules.
>>> Working on this allowed me to learn quite a lot about inner workings of
>>> River - the original implementation that I've presented before had to be
>>> modified (not saying it had to be fixed :) ) but the main idea stayed
>>> the same. This time I think it really covers more use cases.
>>>
>>> Shortly:
>>> 1. We allow annotating classes with Modules. A Module is an object
>>> responsible for loading classes.
>>> 2. There is a new RMIClassLoaderSpi implementation which I called
>>> ModuleClassProvider
>>> 3. ModuleClassProvider manages installed Modules
>>> 4. It also can load classes based on String annotations which are
>>> expected to be either
>>> a) serialized and Base64 encoded Module - the Module is deserialized and
>>> handled as any other Module annotation
>>> b) an old style list of URLs - class loading is delegated to
>>> RequireDlPermProvider - in other words we either load classes from
>>> Modules (which are verified for trust before use) or from URLs but then
>>> we require appropriate DownloadPermissions
>>>
>>> Attached is a multi-module maven project. The modules are:
>>> 1. secure-marshall-stream (which is the implementation of all this + some
>>> not yet finished additional code)
>>> 2. jsk-module-platform which contains modified Jini classes so that it
>>> all works with existing Jini services (to be honest only ClassLoading
>>> really needed to change.
>>> MarshalInputStream/MarshalOutputStream/MarshalledInstance are changed
>>> only to avoid having serialized and Base64 encoded Modules as
>>> annotations
>>>
>>> To run it you need to put jsk-module-platform before jsk-platform on the
>>> classpath (and of course add secure-marshall-stream as well)
>>>
>>> Existing services can be exported with a ModuleExporter:
>>>     private serviceILFactory =
>>> 	
>>> 	new ProxyTrustILFactory(serviceConstraints,
>>> 	
>>>                                 RegistrarPermission.class);
>>>     
>>>     private moduleTrustILFactory =
>>> 	
>>> 	new ModuleTrustILFactory(serviceConstraints,
>>> 	
>>>                                 null);
>>>     
>>>     serverExporter = new ModuleExporter(new
>>>     BasicJeriExporter(serviceEndpoint,
>>>
>>> serviceILFactory), new BasicJeriExporter(serviceEndpoint,
>>> moduleTrustILFactory));
>>>
>>> I've done some basic scenario testing which was running Reggie and
>>> Service Browser installed by Jini 2.1 installer. Both Browser and Reggie
>>> policies did not grant any DownloadPermissions.
>>> When exported with BasicJeriExporter lookup of ServiceRegistrar by the
>>> Browser failed with missing DownloadPermission.
>>> When exported with ModuleExporter both Reggie and Browser used
>>> ProxyTrustVerifier to verifify Modules.
>>>
>>> Note - this is strictly a prototype - no comments / junit tests / code
>>> reviews and no real testing.
>>>
>>> If you have any questions / comments - you're very welcome.
>>>
>>> Michal
>>>
>>> On Monday 18 of October 2010 03:08:38 Peter Firmstone wrote:
>>>       
>>>> Notes for fix:
>>>>
>>>> DownloadPermission protects against unauthenticated downloads
>>>> ClassLoadingPermission - new Permission to protect against
>>>> unauthenticated Class loading.
>>>>
>>>> Issues we're addressing in the DOS hole:
>>>>     * Eliminate unauthenticated URL downloads.
>>>>     * Eliminate unmarshalling of unauthenticated code.
>>>>     * Eliminate execution of unauthenticated code.
>>>>     * Eliminate StackOverflowError's in the client thread, caused by
>>>>     
>>>>       sending spurious garbage over InputStream's.
>>>>     
>>>>     * Eliminate StackOverflowError's in the client thread, caused by
>>>>     
>>>>       substituted jar files or URL's from DNS cache poisoning attacks
>>>>       etc.
>>>>
>>>> How?
>>>>
>>>>     * Delay granting DownloadPermission, until remote endpoint has
>>>>     
>>>>       authenticated itself, we trust the remote endpoint to advise a
>>>>       suitable URL, if it authenticates.
>>>>     
>>>>     * Authentication by annotating a reflective proxy (additional to the
>>>>     
>>>>       Codebase String) from the remote endpoint, used for authentication
>>>>       and to provide CodeSource Certificate[]'s.  This may be different
>>>>       to the Service, if a remote object is marshalled elsewhere (eg
>>>>       another client).
>>>>     
>>>>     * Delay granting ClassLoadingPermission, until remote endpoint has
>>>>     
>>>>       authenticated itself and has provided the expected CodeSource
>>>>       Certificate[]'s
>>>>     
>>>>     * Perform unmarshalling in a controlled ExecutorService thread.
>>>>
>>>> So all we're doing different is authenticating the remote end and if it
>>>> authenticates permit downloading and classloading.
>>>>
>>>> There is one more scenario to consider, currently this is a mechanism to
>>>> protect against download and deserialization of unknown code for smart
>>>> proxy's.  But what about Service that only use reflective proxy's and
>>>> don't require downloaded code?
>>>>
>>>> But what if we don't want to grant download permission or class loading
>>>> permission to a Subject we authenticate?
>>>>
>>>> Currently the unmarshalling code doesn't run as the Subject after
>>>> authentication, this means the Permission grant's are only dependent on
>>>> authentication, something Michal pointed out earlier when this was
>>>> proposed.
>>>>
>>>> Now this code can be easily changed so the granting permission operation
>>>> is run as the Subject after authentication, this would allow us to
>>>> distinguish between different Subjects.
>>>>
>>>> The drawback is that performance won't be as good, but it seems the most
>>>> logical and powerful approach.
>>>>
>>>> What do you think?
>>>>
>>>> There is one last obstacle, if Certificates are used to sign the jar
>>>> files, how do you effectively prevent one Subject from using another
>>>> Subject's signed CodeSource's if Code signing is used for isolation of
>>>> separate Subjects namespaces?  A service could deliberately attempt to
>>>> occupy the same namespace as another Service to attempt to gain
>>>> information via shared static variables.  We need to prevent this
>>>> occurring.
>>>>
>>>> This has to be done with the ClassLoader, but during unmarshalling, the
>>>> service proxy has not yet been verified.  The authentication proxy
>>>> delivered with the MarshalInputStream may not have the same Subject as
>>>> the Service, it could be a third party.
>>>>
>>>> Could it be that when the smart proxy is unmarshalled, and executed as
>>>> it's Subject, it must contain a Certificate matching the signer of the
>>>> Codebase?
>>>>
>>>> We're on the cusp of solving this problem, thoughts?
>>>>
>>>> Cheers,
>>>>
>>>> Peter.
>>>>
>>>> Peter Firmstone (JIRA) wrote:
>>>>         
>>>>> Denial of Service during unmarshalling of smart proxy's
>>>>> -------------------------------------------------------
>>>>>
>>>>>                  Key: RIVER-362
>>>>>                  URL: https://issues.apache.org/jira/browse/RIVER-362
>>>>>              
>>>>>              Project: River
>>>>>           
>>>>>           Issue Type: Bug
>>>>>          
>>>>>          Environment: Untrusted networks
>>>>>          
>>>>>             Reporter: Peter Firmstone
>>>>>
>>>>> During unmarshalling of smart proxy's there's a period before the proxy
>>>>> has been verified (authenticated) where deserialization methods are
>>>>> executed on untrusted code, the potential exists for untrusted code to
>>>>> perform denial of service.
>>>>>           
>
>   


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Hi Michal,

Sorry for taking time to respond, I've been busy and am still digesting 
the code.

Michal Kleczek wrote:
> In my code there is a simple hack to force creating a different ClassLoader for 
> each unique Module - before calling to a delegate RMIClassProviderSpi I set a 
> TCCL to a new ClassLoader that is unique to the Module. (That is also the 
> reason I had to provide a slightly modified version of BasicJeriTrustVerifier so 
> that not the proxy ClassLoader but also its parent are verified)
> See AbstractRmiModule for details.
>
> Module uniqueness: two Modules are considered the same iff their equals returns 
> true.
>
> In case of ProxyTrustModule (which is the most interesting) - two 
> ProxyTrustModules are equal when their codebases are equal and their 
> ProxyTrusts are equal. so for two different services - each providing its own 
> ProxyTrust for Modules - we create two different ClassLoaders regardless of the 
> codebases. (This is not based on Subject but on service proxy identity)
> Basing it on Subject would be a little tricky IMHO because actual service 
> Principals are dependent on what the client requires.
>   
Ok I see your point, we should be using service proxy identity, not the 
Subject.  A server might use a number of subjects. Since not all proxy's 
are services, would it be better to use the BasicObjectEndpoint identity.

ProxyTrust, doesn't by default implement equals or hashcode, if the 
client is handed a reference to a remote object, that is a smart proxy, 
from another client, it could end up with two separate instances if 
ProxyTrust uses the default Object equals implementation.

So thinking about it a little more, perhaps we could use the Uuid of the 
BasicObjectEndpoint?

Doing so has a significant drawback, limiting sharing of common bytecode.

If we weren't worried about security, for efficiency reasons we'd keep 
all services with identical code in the same ClassLoader, or name space, 
the security risk is the service proxy object of one provider could 
communicate with another with different privileges using class variables.

Another reason for not using the Subject, even if there was no immediate 
security risk due to sharing of class variables, the services within the 
ProtectionDomain must have identical permissions, under identical 
circumstances, but because all proxy's cannot be discovered and verified 
at the same time, this would not be easily possible.

So it might be wise to remain on the conservative side and designate a 
ClassLoader for each unique remote object, and cache codebases, to 
reduce downloading.

Regards,

Peter.
> We can sign codebases using SignedRmiModule which - beside codebase - carries 
> signature information with it and can be verified locally by 
> SignedRmiModuleVerifier (not yet finished). I also thought about delegating 
> signature verification work to a (remote) service that would be carried by 
> SignedRmiModule and verified for trust before used by the client to verify the 
> actual signature.
>
> The whole design was based on Jini 2.1 so no dynamic CodeBase grants are 
> necessary.
>
> Regards,
> Michal
>
> On Tuesday 19 of October 2010 03:10:50 Peter Firmstone wrote:
>   
>> Michal,
>>
>> You compose an incredible amount of code in a very short time, I haven't
>> yet digested it.
>>
>> I'm still trying to figure out how a Service proxy's namespace can be
>> restricted to a single Subject (the Service authenticates itself with).
>>
>> To avoid security vulnerabilities, caused by shared class state.
>>
>> Classes within a ClassLoader belonging to a particular Service should
>> have no visibility outside their ClassLoader, external classes should
>> only be able to interact via Service API, they shouldn't be able to
>> create objects using constructors from within the service proxy's
>> namespace.  The Service proxy needs to have isolated visibility.
>>
>> Objects within the proxy's private namespace are constructed during
>> deserialization.
>>
>> We could require that a proxy codebase must be signed, we could also
>> require that the Subject, when it authenticates has the same Certificate
>> as the codebase.  Since Certificate's have chains of trust, which can
>> grow longer, it would only be the first Certificate in each
>> Certificate[] array (Subject and CodeSource) that would be checked.
>>
>> Using Codebase Certificate's has an advantage over message digests
>> because the implementation can change.
>>
>> After a smart proxy has been unmarshalled, if it is discovered that the
>> Certificates don't match, this indicates the proxy has been downloaded
>> into the wrong namespace, this proxy can be safely discarded.
>>
>> Cheers,
>>
>> Peter.
>>
>> Michal Kleczek wrote:
>>     
>>> Folks,
>>>
>>> I've managed to create a prototype implementation of the idea of
>>> annotating classes with Modules.
>>> Working on this allowed me to learn quite a lot about inner workings of
>>> River - the original implementation that I've presented before had to be
>>> modified (not saying it had to be fixed :) ) but the main idea stayed
>>> the same. This time I think it really covers more use cases.
>>>
>>> Shortly:
>>> 1. We allow annotating classes with Modules. A Module is an object
>>> responsible for loading classes.
>>> 2. There is a new RMIClassLoaderSpi implementation which I called
>>> ModuleClassProvider
>>> 3. ModuleClassProvider manages installed Modules
>>> 4. It also can load classes based on String annotations which are
>>> expected to be either
>>> a) serialized and Base64 encoded Module - the Module is deserialized and
>>> handled as any other Module annotation
>>> b) an old style list of URLs - class loading is delegated to
>>> RequireDlPermProvider - in other words we either load classes from
>>> Modules (which are verified for trust before use) or from URLs but then
>>> we require appropriate DownloadPermissions
>>>
>>> Attached is a multi-module maven project. The modules are:
>>> 1. secure-marshall-stream (which is the implementation of all this + some
>>> not yet finished additional code)
>>> 2. jsk-module-platform which contains modified Jini classes so that it
>>> all works with existing Jini services (to be honest only ClassLoading
>>> really needed to change.
>>> MarshalInputStream/MarshalOutputStream/MarshalledInstance are changed
>>> only to avoid having serialized and Base64 encoded Modules as
>>> annotations
>>>
>>> To run it you need to put jsk-module-platform before jsk-platform on the
>>> classpath (and of course add secure-marshall-stream as well)
>>>
>>> Existing services can be exported with a ModuleExporter:
>>>     private serviceILFactory =
>>> 	
>>> 	new ProxyTrustILFactory(serviceConstraints,
>>> 	
>>>                                 RegistrarPermission.class);
>>>     
>>>     private moduleTrustILFactory =
>>> 	
>>> 	new ModuleTrustILFactory(serviceConstraints,
>>> 	
>>>                                 null);
>>>     
>>>     serverExporter = new ModuleExporter(new
>>>     BasicJeriExporter(serviceEndpoint,
>>>
>>> serviceILFactory), new BasicJeriExporter(serviceEndpoint,
>>> moduleTrustILFactory));
>>>
>>> I've done some basic scenario testing which was running Reggie and
>>> Service Browser installed by Jini 2.1 installer. Both Browser and Reggie
>>> policies did not grant any DownloadPermissions.
>>> When exported with BasicJeriExporter lookup of ServiceRegistrar by the
>>> Browser failed with missing DownloadPermission.
>>> When exported with ModuleExporter both Reggie and Browser used
>>> ProxyTrustVerifier to verifify Modules.
>>>
>>> Note - this is strictly a prototype - no comments / junit tests / code
>>> reviews and no real testing.
>>>
>>> If you have any questions / comments - you're very welcome.
>>>
>>> Michal
>>>
>>> On Monday 18 of October 2010 03:08:38 Peter Firmstone wrote:
>>>       
>>>> Notes for fix:
>>>>
>>>> DownloadPermission protects against unauthenticated downloads
>>>> ClassLoadingPermission - new Permission to protect against
>>>> unauthenticated Class loading.
>>>>
>>>> Issues we're addressing in the DOS hole:
>>>>     * Eliminate unauthenticated URL downloads.
>>>>     * Eliminate unmarshalling of unauthenticated code.
>>>>     * Eliminate execution of unauthenticated code.
>>>>     * Eliminate StackOverflowError's in the client thread, caused by
>>>>     
>>>>       sending spurious garbage over InputStream's.
>>>>     
>>>>     * Eliminate StackOverflowError's in the client thread, caused by
>>>>     
>>>>       substituted jar files or URL's from DNS cache poisoning attacks
>>>>       etc.
>>>>
>>>> How?
>>>>
>>>>     * Delay granting DownloadPermission, until remote endpoint has
>>>>     
>>>>       authenticated itself, we trust the remote endpoint to advise a
>>>>       suitable URL, if it authenticates.
>>>>     
>>>>     * Authentication by annotating a reflective proxy (additional to the
>>>>     
>>>>       Codebase String) from the remote endpoint, used for authentication
>>>>       and to provide CodeSource Certificate[]'s.  This may be different
>>>>       to the Service, if a remote object is marshalled elsewhere (eg
>>>>       another client).
>>>>     
>>>>     * Delay granting ClassLoadingPermission, until remote endpoint has
>>>>     
>>>>       authenticated itself and has provided the expected CodeSource
>>>>       Certificate[]'s
>>>>     
>>>>     * Perform unmarshalling in a controlled ExecutorService thread.
>>>>
>>>> So all we're doing different is authenticating the remote end and if it
>>>> authenticates permit downloading and classloading.
>>>>
>>>> There is one more scenario to consider, currently this is a mechanism to
>>>> protect against download and deserialization of unknown code for smart
>>>> proxy's.  But what about Service that only use reflective proxy's and
>>>> don't require downloaded code?
>>>>
>>>> But what if we don't want to grant download permission or class loading
>>>> permission to a Subject we authenticate?
>>>>
>>>> Currently the unmarshalling code doesn't run as the Subject after
>>>> authentication, this means the Permission grant's are only dependent on
>>>> authentication, something Michal pointed out earlier when this was
>>>> proposed.
>>>>
>>>> Now this code can be easily changed so the granting permission operation
>>>> is run as the Subject after authentication, this would allow us to
>>>> distinguish between different Subjects.
>>>>
>>>> The drawback is that performance won't be as good, but it seems the most
>>>> logical and powerful approach.
>>>>
>>>> What do you think?
>>>>
>>>> There is one last obstacle, if Certificates are used to sign the jar
>>>> files, how do you effectively prevent one Subject from using another
>>>> Subject's signed CodeSource's if Code signing is used for isolation of
>>>> separate Subjects namespaces?  A service could deliberately attempt to
>>>> occupy the same namespace as another Service to attempt to gain
>>>> information via shared static variables.  We need to prevent this
>>>> occurring.
>>>>
>>>> This has to be done with the ClassLoader, but during unmarshalling, the
>>>> service proxy has not yet been verified.  The authentication proxy
>>>> delivered with the MarshalInputStream may not have the same Subject as
>>>> the Service, it could be a third party.
>>>>
>>>> Could it be that when the smart proxy is unmarshalled, and executed as
>>>> it's Subject, it must contain a Certificate matching the signer of the
>>>> Codebase?
>>>>
>>>> We're on the cusp of solving this problem, thoughts?
>>>>
>>>> Cheers,
>>>>
>>>> Peter.
>>>>
>>>> Peter Firmstone (JIRA) wrote:
>>>>         
>>>>> Denial of Service during unmarshalling of smart proxy's
>>>>> -------------------------------------------------------
>>>>>
>>>>>                  Key: RIVER-362
>>>>>                  URL: https://issues.apache.org/jira/browse/RIVER-362
>>>>>              
>>>>>              Project: River
>>>>>           
>>>>>           Issue Type: Bug
>>>>>          
>>>>>          Environment: Untrusted networks
>>>>>          
>>>>>             Reporter: Peter Firmstone
>>>>>
>>>>> During unmarshalling of smart proxy's there's a period before the proxy
>>>>> has been verified (authenticated) where deserialization methods are
>>>>> executed on untrusted code, the potential exists for untrusted code to
>>>>> perform denial of service.
>>>>>           
>
>   


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Michal Kleczek <mi...@xpro.biz>.
In my code there is a simple hack to force creating a different ClassLoader for 
each unique Module - before calling to a delegate RMIClassProviderSpi I set a 
TCCL to a new ClassLoader that is unique to the Module. (That is also the 
reason I had to provide a slightly modified version of BasicJeriTrustVerifier so 
that not the proxy ClassLoader but also its parent are verified)
See AbstractRmiModule for details.

Module uniqueness: two Modules are considered the same iff their equals returns 
true.

In case of ProxyTrustModule (which is the most interesting) - two 
ProxyTrustModules are equal when their codebases are equal and their 
ProxyTrusts are equal. so for two different services - each providing its own 
ProxyTrust for Modules - we create two different ClassLoaders regardless of the 
codebases. (This is not based on Subject but on service proxy identity)
Basing it on Subject would be a little tricky IMHO because actual service 
Principals are dependent on what the client requires.

We can sign codebases using SignedRmiModule which - beside codebase - carries 
signature information with it and can be verified locally by 
SignedRmiModuleVerifier (not yet finished). I also thought about delegating 
signature verification work to a (remote) service that would be carried by 
SignedRmiModule and verified for trust before used by the client to verify the 
actual signature.

The whole design was based on Jini 2.1 so no dynamic CodeBase grants are 
necessary.

Regards,
Michal

On Tuesday 19 of October 2010 03:10:50 Peter Firmstone wrote:
> Michal,
> 
> You compose an incredible amount of code in a very short time, I haven't
> yet digested it.
> 
> I'm still trying to figure out how a Service proxy's namespace can be
> restricted to a single Subject (the Service authenticates itself with).
> 
> To avoid security vulnerabilities, caused by shared class state.
> 
> Classes within a ClassLoader belonging to a particular Service should
> have no visibility outside their ClassLoader, external classes should
> only be able to interact via Service API, they shouldn't be able to
> create objects using constructors from within the service proxy's
> namespace.  The Service proxy needs to have isolated visibility.
> 
> Objects within the proxy's private namespace are constructed during
> deserialization.
> 
> We could require that a proxy codebase must be signed, we could also
> require that the Subject, when it authenticates has the same Certificate
> as the codebase.  Since Certificate's have chains of trust, which can
> grow longer, it would only be the first Certificate in each
> Certificate[] array (Subject and CodeSource) that would be checked.
> 
> Using Codebase Certificate's has an advantage over message digests
> because the implementation can change.
> 
> After a smart proxy has been unmarshalled, if it is discovered that the
> Certificates don't match, this indicates the proxy has been downloaded
> into the wrong namespace, this proxy can be safely discarded.
> 
> Cheers,
> 
> Peter.
> 
> Michal Kleczek wrote:
> > Folks,
> > 
> > I've managed to create a prototype implementation of the idea of
> > annotating classes with Modules.
> > Working on this allowed me to learn quite a lot about inner workings of
> > River - the original implementation that I've presented before had to be
> > modified (not saying it had to be fixed :) ) but the main idea stayed
> > the same. This time I think it really covers more use cases.
> > 
> > Shortly:
> > 1. We allow annotating classes with Modules. A Module is an object
> > responsible for loading classes.
> > 2. There is a new RMIClassLoaderSpi implementation which I called
> > ModuleClassProvider
> > 3. ModuleClassProvider manages installed Modules
> > 4. It also can load classes based on String annotations which are
> > expected to be either
> > a) serialized and Base64 encoded Module - the Module is deserialized and
> > handled as any other Module annotation
> > b) an old style list of URLs - class loading is delegated to
> > RequireDlPermProvider - in other words we either load classes from
> > Modules (which are verified for trust before use) or from URLs but then
> > we require appropriate DownloadPermissions
> > 
> > Attached is a multi-module maven project. The modules are:
> > 1. secure-marshall-stream (which is the implementation of all this + some
> > not yet finished additional code)
> > 2. jsk-module-platform which contains modified Jini classes so that it
> > all works with existing Jini services (to be honest only ClassLoading
> > really needed to change.
> > MarshalInputStream/MarshalOutputStream/MarshalledInstance are changed
> > only to avoid having serialized and Base64 encoded Modules as
> > annotations
> > 
> > To run it you need to put jsk-module-platform before jsk-platform on the
> > classpath (and of course add secure-marshall-stream as well)
> > 
> > Existing services can be exported with a ModuleExporter:
> >     private serviceILFactory =
> > 	
> > 	new ProxyTrustILFactory(serviceConstraints,
> > 	
> >                                 RegistrarPermission.class);
> >     
> >     private moduleTrustILFactory =
> > 	
> > 	new ModuleTrustILFactory(serviceConstraints,
> > 	
> >                                 null);
> >     
> >     serverExporter = new ModuleExporter(new
> >     BasicJeriExporter(serviceEndpoint,
> > 
> > serviceILFactory), new BasicJeriExporter(serviceEndpoint,
> > moduleTrustILFactory));
> > 
> > I've done some basic scenario testing which was running Reggie and
> > Service Browser installed by Jini 2.1 installer. Both Browser and Reggie
> > policies did not grant any DownloadPermissions.
> > When exported with BasicJeriExporter lookup of ServiceRegistrar by the
> > Browser failed with missing DownloadPermission.
> > When exported with ModuleExporter both Reggie and Browser used
> > ProxyTrustVerifier to verifify Modules.
> > 
> > Note - this is strictly a prototype - no comments / junit tests / code
> > reviews and no real testing.
> > 
> > If you have any questions / comments - you're very welcome.
> > 
> > Michal
> > 
> > On Monday 18 of October 2010 03:08:38 Peter Firmstone wrote:
> >> Notes for fix:
> >> 
> >> DownloadPermission protects against unauthenticated downloads
> >> ClassLoadingPermission - new Permission to protect against
> >> unauthenticated Class loading.
> >> 
> >> Issues we're addressing in the DOS hole:
> >>     * Eliminate unauthenticated URL downloads.
> >>     * Eliminate unmarshalling of unauthenticated code.
> >>     * Eliminate execution of unauthenticated code.
> >>     * Eliminate StackOverflowError's in the client thread, caused by
> >>     
> >>       sending spurious garbage over InputStream's.
> >>     
> >>     * Eliminate StackOverflowError's in the client thread, caused by
> >>     
> >>       substituted jar files or URL's from DNS cache poisoning attacks
> >>       etc.
> >> 
> >> How?
> >> 
> >>     * Delay granting DownloadPermission, until remote endpoint has
> >>     
> >>       authenticated itself, we trust the remote endpoint to advise a
> >>       suitable URL, if it authenticates.
> >>     
> >>     * Authentication by annotating a reflective proxy (additional to the
> >>     
> >>       Codebase String) from the remote endpoint, used for authentication
> >>       and to provide CodeSource Certificate[]'s.  This may be different
> >>       to the Service, if a remote object is marshalled elsewhere (eg
> >>       another client).
> >>     
> >>     * Delay granting ClassLoadingPermission, until remote endpoint has
> >>     
> >>       authenticated itself and has provided the expected CodeSource
> >>       Certificate[]'s
> >>     
> >>     * Perform unmarshalling in a controlled ExecutorService thread.
> >> 
> >> So all we're doing different is authenticating the remote end and if it
> >> authenticates permit downloading and classloading.
> >> 
> >> There is one more scenario to consider, currently this is a mechanism to
> >> protect against download and deserialization of unknown code for smart
> >> proxy's.  But what about Service that only use reflective proxy's and
> >> don't require downloaded code?
> >> 
> >> But what if we don't want to grant download permission or class loading
> >> permission to a Subject we authenticate?
> >> 
> >> Currently the unmarshalling code doesn't run as the Subject after
> >> authentication, this means the Permission grant's are only dependent on
> >> authentication, something Michal pointed out earlier when this was
> >> proposed.
> >> 
> >> Now this code can be easily changed so the granting permission operation
> >> is run as the Subject after authentication, this would allow us to
> >> distinguish between different Subjects.
> >> 
> >> The drawback is that performance won't be as good, but it seems the most
> >> logical and powerful approach.
> >> 
> >> What do you think?
> >> 
> >> There is one last obstacle, if Certificates are used to sign the jar
> >> files, how do you effectively prevent one Subject from using another
> >> Subject's signed CodeSource's if Code signing is used for isolation of
> >> separate Subjects namespaces?  A service could deliberately attempt to
> >> occupy the same namespace as another Service to attempt to gain
> >> information via shared static variables.  We need to prevent this
> >> occurring.
> >> 
> >> This has to be done with the ClassLoader, but during unmarshalling, the
> >> service proxy has not yet been verified.  The authentication proxy
> >> delivered with the MarshalInputStream may not have the same Subject as
> >> the Service, it could be a third party.
> >> 
> >> Could it be that when the smart proxy is unmarshalled, and executed as
> >> it's Subject, it must contain a Certificate matching the signer of the
> >> Codebase?
> >> 
> >> We're on the cusp of solving this problem, thoughts?
> >> 
> >> Cheers,
> >> 
> >> Peter.
> >> 
> >> Peter Firmstone (JIRA) wrote:
> >>> Denial of Service during unmarshalling of smart proxy's
> >>> -------------------------------------------------------
> >>> 
> >>>                  Key: RIVER-362
> >>>                  URL: https://issues.apache.org/jira/browse/RIVER-362
> >>>              
> >>>              Project: River
> >>>           
> >>>           Issue Type: Bug
> >>>          
> >>>          Environment: Untrusted networks
> >>>          
> >>>             Reporter: Peter Firmstone
> >>> 
> >>> During unmarshalling of smart proxy's there's a period before the proxy
> >>> has been verified (authenticated) where deserialization methods are
> >>> executed on untrusted code, the potential exists for untrusted code to
> >>> perform denial of service.

Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Peter Firmstone <ji...@zeus.net.au>.
Michal,

You compose an incredible amount of code in a very short time, I haven't 
yet digested it.

I'm still trying to figure out how a Service proxy's namespace can be 
restricted to a single Subject (the Service authenticates itself with).

To avoid security vulnerabilities, caused by shared class state.

Classes within a ClassLoader belonging to a particular Service should 
have no visibility outside their ClassLoader, external classes should 
only be able to interact via Service API, they shouldn't be able to 
create objects using constructors from within the service proxy's 
namespace.  The Service proxy needs to have isolated visibility.

Objects within the proxy's private namespace are constructed during 
deserialization.

We could require that a proxy codebase must be signed, we could also 
require that the Subject, when it authenticates has the same Certificate 
as the codebase.  Since Certificate's have chains of trust, which can 
grow longer, it would only be the first Certificate in each 
Certificate[] array (Subject and CodeSource) that would be checked.

Using Codebase Certificate's has an advantage over message digests 
because the implementation can change.

After a smart proxy has been unmarshalled, if it is discovered that the 
Certificates don't match, this indicates the proxy has been downloaded 
into the wrong namespace, this proxy can be safely discarded.

Cheers,

Peter.

Michal Kleczek wrote:
> Folks,
>
> I've managed to create a prototype implementation of the idea of annotating 
> classes with Modules.
> Working on this allowed me to learn quite a lot about inner workings of River 
> - the original implementation that I've presented before had to be modified 
> (not saying it had to be fixed :) ) but the main idea stayed the same. This 
> time I think it really covers more use cases.
>
> Shortly:
> 1. We allow annotating classes with Modules. A Module is an object responsible 
> for loading classes.
> 2. There is a new RMIClassLoaderSpi implementation which I called 
> ModuleClassProvider
> 3. ModuleClassProvider manages installed Modules
> 4. It also can load classes based on String annotations which are expected to 
> be either
> a) serialized and Base64 encoded Module - the Module is deserialized and 
> handled as any other Module annotation
> b) an old style list of URLs - class loading is delegated to 
> RequireDlPermProvider - in other words we either load classes from Modules 
> (which are verified for trust before use) or from URLs but then we require 
> appropriate DownloadPermissions
>
> Attached is a multi-module maven project. The modules are:
> 1. secure-marshall-stream (which is the implementation of all this + some not 
> yet finished additional code)
> 2. jsk-module-platform which contains modified Jini classes so that it all 
> works with existing Jini services (to be honest only ClassLoading really 
> needed to change. MarshalInputStream/MarshalOutputStream/MarshalledInstance 
> are changed only to avoid having serialized and Base64 encoded Modules as 
> annotations
>
> To run it you need to put jsk-module-platform before jsk-platform on the 
> classpath (and of course add secure-marshall-stream as well)
>
> Existing services can be exported with a ModuleExporter:
>
>     private serviceILFactory =
> 	new ProxyTrustILFactory(serviceConstraints,
>                                 RegistrarPermission.class);
>     private moduleTrustILFactory =
> 	new ModuleTrustILFactory(serviceConstraints,
>                                 null);
>
>     serverExporter = new ModuleExporter(new BasicJeriExporter(serviceEndpoint, 
> serviceILFactory), new BasicJeriExporter(serviceEndpoint, 
> moduleTrustILFactory));
>
> I've done some basic scenario testing which was running Reggie and Service 
> Browser installed by Jini 2.1 installer. Both Browser and Reggie policies did 
> not grant any DownloadPermissions.
> When exported with BasicJeriExporter lookup of ServiceRegistrar by the Browser 
> failed with missing DownloadPermission.
> When exported with ModuleExporter both Reggie and Browser used 
> ProxyTrustVerifier to verifify Modules.
>
> Note - this is strictly a prototype - no comments / junit tests / code reviews 
> and no real testing.
>
> If you have any questions / comments - you're very welcome.
>
> Michal
>
> On Monday 18 of October 2010 03:08:38 Peter Firmstone wrote:
>   
>> Notes for fix:
>>
>> DownloadPermission protects against unauthenticated downloads
>> ClassLoadingPermission - new Permission to protect against
>> unauthenticated Class loading.
>>
>> Issues we're addressing in the DOS hole:
>>
>>     * Eliminate unauthenticated URL downloads.
>>     * Eliminate unmarshalling of unauthenticated code.
>>     * Eliminate execution of unauthenticated code.
>>     * Eliminate StackOverflowError's in the client thread, caused by
>>       sending spurious garbage over InputStream's.
>>     * Eliminate StackOverflowError's in the client thread, caused by
>>       substituted jar files or URL's from DNS cache poisoning attacks etc.
>>
>> How?
>>
>>     * Delay granting DownloadPermission, until remote endpoint has
>>       authenticated itself, we trust the remote endpoint to advise a
>>       suitable URL, if it authenticates.
>>     * Authentication by annotating a reflective proxy (additional to the
>>       Codebase String) from the remote endpoint, used for authentication
>>       and to provide CodeSource Certificate[]'s.  This may be different
>>       to the Service, if a remote object is marshalled elsewhere (eg
>>       another client).
>>     * Delay granting ClassLoadingPermission, until remote endpoint has
>>       authenticated itself and has provided the expected CodeSource
>>       Certificate[]'s
>>     * Perform unmarshalling in a controlled ExecutorService thread.
>>
>> So all we're doing different is authenticating the remote end and if it
>> authenticates permit downloading and classloading.
>>
>> There is one more scenario to consider, currently this is a mechanism to
>> protect against download and deserialization of unknown code for smart
>> proxy's.  But what about Service that only use reflective proxy's and
>> don't require downloaded code?
>>
>> But what if we don't want to grant download permission or class loading
>> permission to a Subject we authenticate?
>>
>> Currently the unmarshalling code doesn't run as the Subject after
>> authentication, this means the Permission grant's are only dependent on
>> authentication, something Michal pointed out earlier when this was
>> proposed.
>>
>> Now this code can be easily changed so the granting permission operation
>> is run as the Subject after authentication, this would allow us to
>> distinguish between different Subjects.
>>
>> The drawback is that performance won't be as good, but it seems the most
>> logical and powerful approach.
>>
>> What do you think?
>>
>> There is one last obstacle, if Certificates are used to sign the jar
>> files, how do you effectively prevent one Subject from using another
>> Subject's signed CodeSource's if Code signing is used for isolation of
>> separate Subjects namespaces?  A service could deliberately attempt to
>> occupy the same namespace as another Service to attempt to gain
>> information via shared static variables.  We need to prevent this
>> occurring.
>>
>> This has to be done with the ClassLoader, but during unmarshalling, the
>> service proxy has not yet been verified.  The authentication proxy
>> delivered with the MarshalInputStream may not have the same Subject as
>> the Service, it could be a third party.
>>
>> Could it be that when the smart proxy is unmarshalled, and executed as
>> it's Subject, it must contain a Certificate matching the signer of the
>> Codebase?
>>
>> We're on the cusp of solving this problem, thoughts?
>>
>> Cheers,
>>
>> Peter.
>>
>> Peter Firmstone (JIRA) wrote:
>>     
>>> Denial of Service during unmarshalling of smart proxy's
>>> -------------------------------------------------------
>>>
>>>                  Key: RIVER-362
>>>                  URL: https://issues.apache.org/jira/browse/RIVER-362
>>>              
>>>              Project: River
>>>           
>>>           Issue Type: Bug
>>>          
>>>          Environment: Untrusted networks
>>>          
>>>             Reporter: Peter Firmstone
>>>
>>> During unmarshalling of smart proxy's there's a period before the proxy
>>> has been verified (authenticated) where deserialization methods are
>>> executed on untrusted code, the potential exists for untrusted code to
>>> perform denial of service.
>>>       


Re: [jira] Created: (RIVER-362) Denial of Service during unmarshalling of smart proxy's

Posted by Michal Kleczek <mi...@xpro.biz>.
Folks,

I've managed to create a prototype implementation of the idea of annotating 
classes with Modules.
Working on this allowed me to learn quite a lot about inner workings of River 
- the original implementation that I've presented before had to be modified 
(not saying it had to be fixed :) ) but the main idea stayed the same. This 
time I think it really covers more use cases.

Shortly:
1. We allow annotating classes with Modules. A Module is an object responsible 
for loading classes.
2. There is a new RMIClassLoaderSpi implementation which I called 
ModuleClassProvider
3. ModuleClassProvider manages installed Modules
4. It also can load classes based on String annotations which are expected to 
be either
a) serialized and Base64 encoded Module - the Module is deserialized and 
handled as any other Module annotation
b) an old style list of URLs - class loading is delegated to 
RequireDlPermProvider - in other words we either load classes from Modules 
(which are verified for trust before use) or from URLs but then we require 
appropriate DownloadPermissions

Attached is a multi-module maven project. The modules are:
1. secure-marshall-stream (which is the implementation of all this + some not 
yet finished additional code)
2. jsk-module-platform which contains modified Jini classes so that it all 
works with existing Jini services (to be honest only ClassLoading really 
needed to change. MarshalInputStream/MarshalOutputStream/MarshalledInstance 
are changed only to avoid having serialized and Base64 encoded Modules as 
annotations

To run it you need to put jsk-module-platform before jsk-platform on the 
classpath (and of course add secure-marshall-stream as well)

Existing services can be exported with a ModuleExporter:

    private serviceILFactory =
	new ProxyTrustILFactory(serviceConstraints,
                                RegistrarPermission.class);
    private moduleTrustILFactory =
	new ModuleTrustILFactory(serviceConstraints,
                                null);

    serverExporter = new ModuleExporter(new BasicJeriExporter(serviceEndpoint, 
serviceILFactory), new BasicJeriExporter(serviceEndpoint, 
moduleTrustILFactory));

I've done some basic scenario testing which was running Reggie and Service 
Browser installed by Jini 2.1 installer. Both Browser and Reggie policies did 
not grant any DownloadPermissions.
When exported with BasicJeriExporter lookup of ServiceRegistrar by the Browser 
failed with missing DownloadPermission.
When exported with ModuleExporter both Reggie and Browser used 
ProxyTrustVerifier to verifify Modules.

Note - this is strictly a prototype - no comments / junit tests / code reviews 
and no real testing.

If you have any questions / comments - you're very welcome.

Michal

On Monday 18 of October 2010 03:08:38 Peter Firmstone wrote:
> Notes for fix:
> 
> DownloadPermission protects against unauthenticated downloads
> ClassLoadingPermission - new Permission to protect against
> unauthenticated Class loading.
> 
> Issues we're addressing in the DOS hole:
> 
>     * Eliminate unauthenticated URL downloads.
>     * Eliminate unmarshalling of unauthenticated code.
>     * Eliminate execution of unauthenticated code.
>     * Eliminate StackOverflowError's in the client thread, caused by
>       sending spurious garbage over InputStream's.
>     * Eliminate StackOverflowError's in the client thread, caused by
>       substituted jar files or URL's from DNS cache poisoning attacks etc.
> 
> How?
> 
>     * Delay granting DownloadPermission, until remote endpoint has
>       authenticated itself, we trust the remote endpoint to advise a
>       suitable URL, if it authenticates.
>     * Authentication by annotating a reflective proxy (additional to the
>       Codebase String) from the remote endpoint, used for authentication
>       and to provide CodeSource Certificate[]'s.  This may be different
>       to the Service, if a remote object is marshalled elsewhere (eg
>       another client).
>     * Delay granting ClassLoadingPermission, until remote endpoint has
>       authenticated itself and has provided the expected CodeSource
>       Certificate[]'s
>     * Perform unmarshalling in a controlled ExecutorService thread.
> 
> So all we're doing different is authenticating the remote end and if it
> authenticates permit downloading and classloading.
> 
> There is one more scenario to consider, currently this is a mechanism to
> protect against download and deserialization of unknown code for smart
> proxy's.  But what about Service that only use reflective proxy's and
> don't require downloaded code?
> 
> But what if we don't want to grant download permission or class loading
> permission to a Subject we authenticate?
> 
> Currently the unmarshalling code doesn't run as the Subject after
> authentication, this means the Permission grant's are only dependent on
> authentication, something Michal pointed out earlier when this was
> proposed.
> 
> Now this code can be easily changed so the granting permission operation
> is run as the Subject after authentication, this would allow us to
> distinguish between different Subjects.
> 
> The drawback is that performance won't be as good, but it seems the most
> logical and powerful approach.
> 
> What do you think?
> 
> There is one last obstacle, if Certificates are used to sign the jar
> files, how do you effectively prevent one Subject from using another
> Subject's signed CodeSource's if Code signing is used for isolation of
> separate Subjects namespaces?  A service could deliberately attempt to
> occupy the same namespace as another Service to attempt to gain
> information via shared static variables.  We need to prevent this
> occurring.
> 
> This has to be done with the ClassLoader, but during unmarshalling, the
> service proxy has not yet been verified.  The authentication proxy
> delivered with the MarshalInputStream may not have the same Subject as
> the Service, it could be a third party.
> 
> Could it be that when the smart proxy is unmarshalled, and executed as
> it's Subject, it must contain a Certificate matching the signer of the
> Codebase?
> 
> We're on the cusp of solving this problem, thoughts?
> 
> Cheers,
> 
> Peter.
> 
> Peter Firmstone (JIRA) wrote:
> > Denial of Service during unmarshalling of smart proxy's
> > -------------------------------------------------------
> > 
> >                  Key: RIVER-362
> >                  URL: https://issues.apache.org/jira/browse/RIVER-362
> >              
> >              Project: River
> >           
> >           Issue Type: Bug
> >          
> >          Environment: Untrusted networks
> >          
> >             Reporter: Peter Firmstone
> > 
> > During unmarshalling of smart proxy's there's a period before the proxy
> > has been verified (authenticated) where deserialization methods are
> > executed on untrusted code, the potential exists for untrusted code to
> > perform denial of service.