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/05/21 08:59:28 UTC

Re: Codebase service? --Security Help.

To overcome the problem of all SecurityManager.checkPermission(perm) 
always throwing an Exception caused by a *-api.jar file being present on 
the stack and having no Permissions:

I could create an implementation of DomainCombiner, that removes 
ProtectionDomains of *-api.jar to create a new AccessControlContext that 
can be passed to the two method argument of 
SecurityManger.checkPermission(permission, context) or 
AccessController.doPrivileged(action, context).

A utility class could create the new AccessControlContext.

I wouldn't need to worry if *-api.jar classes could access the utility, 
because the ProtectionDomain of the *-api.jar would have no 
permissions.  The utility would only be used by classes that *-api.jar 
can't see to perform privileged actions.

That way the *-api.jar ProtectionDomain could continue to have no 
Permissions and we wouldn't need to verify their classes.

Any Security experts out there?


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



Then when performing AccessController.doPrivileged, you can't escalate 
privileges with it but you can remove the *-api.jar ProtectionDomain 
from the context.

Could you use this to execute a Trojan hidden in an *-api.jar by calling 
it from a rogue proxy?

No, because it only affects subsequent access determinations, why would 
you bother with the Trojan method, if you already had the permissions to 
perform a security sensitive action?

The use of DomainCombiner to remove ProtectionDomain's sounds counter 
intuitive (but appears workable, from reading the source: after 
optimise() is called on the AccessControlContext).

This would be a better security solution than using ClassDep to verify 
security, and will allow Proxy's to perform permission checks with a new 
AccessControlContext, without *-api.jar ProtectionDomain's.

Yep security is hard. Phew!

Can anyone see any problems with it?

Remember this stuff has to exist on the internet, so it has to be 
secure, we could allow dynamic grants, so if you trust an *-api.jar you 
can be less pedantic?

It would only be for using untrusted Service API's.  Eg, you might not 
trust the Service API, however someone you do trust has implemented it 
and you want to grant some trust to their proxy.

Proxy implementers will have to consider the case where a client trusts 
them but not the Service API.

It might take some time to digest this.

Cheers,

Peter.

Peter Firmstone wrote:
> Actually on Second thoughts, this security concern is unfounded 
> (paranoia perhaps, security is hard!), the ProtectionDomain of the 
> *-api.jar will be on the execution stack, the actual Permissions will 
> be those common to all ProtectionDomain's on the caller's stack, so 
> therefore having a ProtectionDomain with no permissions assigned to a 
> *-api.jar will cause the calling thread to have no permissions (as the 
> proxy sees it).
>
> Therefore a proxy, if it is to utilise it's own permission grants, it 
> will need to use AccessController.doPrivileged()
>
> That sounds better.
>
> Anyway there will be no Permissions granted to any *-api.jar, ever as 
> I'm going to utilise the pre java 1.4 ProtectionDomain constructor, 
> that specifically prevents and excludes dynamic Policy grants.  It 
> won't even consult the Policy.
>
> I'm modifying DynamicPolicy to include grants by Certificate[], an 
> *-api.jar that is signed by a trusted certificate chain, still wont 
> gain any permissions.  Can anyone see that as a problem?
>
> The *-api.jar classes must not have dependencies on anything outside 
> of the Jini Platform, Java Platform or other *-api.jar classes.  The 
> reason for this restriction, is if Someone want's to use OSGi or has a 
> dependency on another version of a library, the *-api.jar importing an 
> incompatible version, would obscure it's visibility and cause a 
> runtime error.
>
> These restrictions shouldn't cause a problem for people as they're 
> easy to design around.  It makes security  simpler for developers too. 
> - You don't have to worry about the security of the code in *-api.jar
>
> Cheers,
>
> Peter.
>
> Peter Firmstone wrote:
>> Dennis Reedy wrote:
>>>> Chris, Dennis & Greg, your all spot on with the Service-spec.jar, 
>>>> I'd like to add something to the jar Manifest of these Service 
>>>> Interfaces, to ensure River loads it into the top level 
>>>> ClassLoader.  Any suggestions?
>>>>     
>>>
>>> Why not just support the convention instead of adding configuration?
>>>   
>>
>> Ok.
>>
>> There is one Security Concern that I will have to address with this 
>> Approach:
>>
>> ClassLoader Structure:
>>
>>                 System ClassLoader
>>                         |
>>                Extension ClassLoader (incl jsk-policy.jar)
>>                         |
>>                Jini Platform ClassLoader (incl jsk-platform.jar, 
>> *-api.jar)
>>                         |
>>          _______________|________________
>>         |                                |
>> Application ClassLoader         Proxy ClassLoader's
>>
>>
>> The *-api.jar files will be placed into Jini Platform ClassLoader, so 
>> the only files visible will be the jini platform classes, java 
>> platform classes and any other *-api.jar classes.
>>
>> The *-api.jar classes will have their own ProtectionDomain's without 
>> any Permissions.
>>
>> However this isn't enough to protect us from code that might be 
>> included in the *-api.jar's that use the calling Threads Permissions 
>> to perform security violating actions.
>>
>> Due to these security concerns, we need to place some restrictions on 
>> the API classes:
>>
>>   1. They must not be allowed to depend on anything other than Jini,
>>      Java Platform and other Service-api.jar's
>>   2. They must not be allowed to depend on any Platform classes that
>>      could cause a Security Violation.
>>
>> The Service API code really needs to be verified before loading, to 
>> ensure that it does not utilise any platform classes that perform 
>> security sensitive operations.
>>
>> The ClassDep tool can run a Dependency Analysis on any *-api.jar to 
>> ensure that no security sensitive classes are accessed, prior to 
>> loading.
>>
>> There is some residual risk that as the Java platform evolves, new 
>> classes that perform Security Sensitive actions will be added, which 
>> means the list of restricted classes will need to grow over time.
>>
>> Could the list itself be contained in a Maven Repository, we could 
>> sign, such a list.
>>
>> Thoughts?
>>
>> Peter.
>>
>>
>>
>>
>>
>>
>
>


Re: Codebase service? --Security Help. - Read this first

Posted by Peter Firmstone <ji...@zeus.net.au>.
The problem I'm dealing with below is: you have proxy trust, but don't 
trust the *-api.jar (Service Interface) and a user with less privileges 
than the proxy is accessing it.

The proxy can't perform a SecurityManager permission check against the 
user's Principal because it will throw an Exception, even when the user 
is a privileged, because the permission check is the intersection of all 
ProtectionDomain's on the callers stack.  The ProtectionDomain of 
*-api.jar has no Permission's and is on the stack.

Below I discuss solutions to overcome Proxy's and Clients utilising 
untrusted Service Interfaces (*-api.jar).

I think I have found a suitable solution.  Clients and proxy's can use 
it to perform Security checks and Privileged Actions, but the *-api.jar 
classes can't take advantage of it to subvert Security because of 
ClassLoader isolation.

Peter Firmstone wrote:
> To overcome the problem of all SecurityManager.checkPermission(perm) 
> always throwing an Exception caused by a *-api.jar file being present 
> on the stack and having no Permissions:
>
> I could create an implementation of DomainCombiner, that removes 
> ProtectionDomains of *-api.jar to create a new AccessControlContext 
> that can be passed to the two method argument of 
> SecurityManger.checkPermission(permission, context) or 
> AccessController.doPrivileged(action, context).
>
> A utility class could create the new AccessControlContext.
>
> I wouldn't need to worry if *-api.jar classes could access the 
> utility, because the ProtectionDomain of the *-api.jar would have no 
> permissions.  The utility would only be used by classes that *-api.jar 
> can't see to perform privileged actions.
>
> That way the *-api.jar ProtectionDomain could continue to have no 
> Permissions and we wouldn't need to verify their classes.
>
> Any Security experts out there?
>
>
>                System ClassLoader
>                        |
>               Extension ClassLoader (incl jsk-policy.jar)
>                        |
>               Jini Platform ClassLoader (incl jsk-platform.jar, 
> *-api.jar)
>                        |
>         _______________|________________
>        |                                |
> Application ClassLoader         Proxy ClassLoader's
>
>
>
> Then when performing AccessController.doPrivileged, you can't escalate 
> privileges with it, but you can remove the *-api.jar ProtectionDomain 
> from the context.
>
> Could you use this to execute a Trojan hidden in an *-api.jar by 
> calling it from a rogue proxy?
>
> No, because it only affects subsequent access determinations, why 
> would you bother with the Trojan method, if you already had the 
> permissions to perform a security sensitive action?
>
> The use of DomainCombiner to remove ProtectionDomain's sounds counter 
> intuitive (but appears workable, from reading the source: after 
> optimise() is called on the AccessControlContext).
>
> This would be a better security solution than using ClassDep to verify 
> security, and will allow Proxy's to perform permission checks with a 
> new AccessControlContext, without *-api.jar ProtectionDomain's.
>
> Yep security is hard. Phew!
>
> Can anyone see any problems with it?
>
> Remember this stuff has to exist on the internet, so it has to be 
> secure, we could allow dynamic grants, so if you trust an *-api.jar 
> you can be less pedantic?
>
> It would only be for using untrusted Service API's.  Eg, you might not 
> trust the Service API, however someone you do trust has implemented it 
> and you want to grant some trust to their proxy.
>
> Proxy implementers will have to consider the case where a client 
> trusts them but not the Service API.
>
> It might take some time to digest this.
>
> Cheers,
>
> Peter.
>
> Peter Firmstone wrote:
>> Actually on Second thoughts, this security concern is unfounded 
>> (paranoia perhaps, security is hard!), the ProtectionDomain of the 
>> *-api.jar will be on the execution stack, the actual Permissions will 
>> be those common to all ProtectionDomain's on the caller's stack, so 
>> therefore having a ProtectionDomain with no permissions assigned to a 
>> *-api.jar will cause the calling thread to have no permissions (as 
>> the proxy sees it).
>>
>> Therefore a proxy, if it is to utilise it's own permission grants, it 
>> will need to use AccessController.doPrivileged()
>>
>> That sounds better.
>>
>> Anyway there will be no Permissions granted to any *-api.jar, ever as 
>> I'm going to utilise the pre java 1.4 ProtectionDomain constructor, 
>> that specifically prevents and excludes dynamic Policy grants.  It 
>> won't even consult the Policy.
>>
>> I'm modifying DynamicPolicy to include grants by Certificate[], an 
>> *-api.jar that is signed by a trusted certificate chain, still wont 
>> gain any permissions.  Can anyone see that as a problem?
>>
>> The *-api.jar classes must not have dependencies on anything outside 
>> of the Jini Platform, Java Platform or other *-api.jar classes.  The 
>> reason for this restriction, is if Someone want's to use OSGi or has 
>> a dependency on another version of a library, the *-api.jar importing 
>> an incompatible version, would obscure it's visibility and cause a 
>> runtime error.
>>
>> These restrictions shouldn't cause a problem for people as they're 
>> easy to design around.  It makes security  simpler for developers 
>> too. - You don't have to worry about the security of the code in 
>> *-api.jar
>>
>> Cheers,
>>
>> Peter.
>>
>> Peter Firmstone wrote:
>>> Dennis Reedy wrote:
>>>>> Chris, Dennis & Greg, your all spot on with the Service-spec.jar, 
>>>>> I'd like to add something to the jar Manifest of these Service 
>>>>> Interfaces, to ensure River loads it into the top level 
>>>>> ClassLoader.  Any suggestions?
>>>>>     
>>>>
>>>> Why not just support the convention instead of adding configuration?
>>>>   
>>>
>>> Ok.
>>>
>>> There is one Security Concern that I will have to address with this 
>>> Approach:
>>>
>>> ClassLoader Structure:
>>>
>>>                 System ClassLoader
>>>                         |
>>>                Extension ClassLoader (incl jsk-policy.jar)
>>>                         |
>>>                Jini Platform ClassLoader (incl jsk-platform.jar, 
>>> *-api.jar)
>>>                         |
>>>          _______________|________________
>>>         |                                |
>>> Application ClassLoader         Proxy ClassLoader's
>>>
>>>
>>> The *-api.jar files will be placed into Jini Platform ClassLoader, 
>>> so the only files visible will be the jini platform classes, java 
>>> platform classes and any other *-api.jar classes.
>>>
>>> The *-api.jar classes will have their own ProtectionDomain's without 
>>> any Permissions.
>>>
>>> However this isn't enough to protect us from code that might be 
>>> included in the *-api.jar's that use the calling Threads Permissions 
>>> to perform security violating actions.
>>>
>>> Due to these security concerns, we need to place some restrictions 
>>> on the API classes:
>>>
>>>   1. They must not be allowed to depend on anything other than Jini,
>>>      Java Platform and other Service-api.jar's
>>>   2. They must not be allowed to depend on any Platform classes that
>>>      could cause a Security Violation.
>>>
>>> The Service API code really needs to be verified before loading, to 
>>> ensure that it does not utilise any platform classes that perform 
>>> security sensitive operations.
>>>
>>> The ClassDep tool can run a Dependency Analysis on any *-api.jar to 
>>> ensure that no security sensitive classes are accessed, prior to 
>>> loading.
>>>
>>> There is some residual risk that as the Java platform evolves, new 
>>> classes that perform Security Sensitive actions will be added, which 
>>> means the list of restricted classes will need to grow over time.
>>>
>>> Could the list itself be contained in a Maven Repository, we could 
>>> sign, such a list.
>>>
>>> Thoughts?
>>>
>>> Peter.
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>
>