You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Kłeczek, Michał <mi...@kleczek.org> on 2020/06/05 17:08:48 UTC

Re: Proxy identity behaves unexpectedly for secure services.

Hi Peter,

I think we need to be careful here - basically the semantics should be:

MyServiceProxy originalProxy = ...
MethodConstraints localClientConstraints = ...

// THIS IS IMPORTANT!!!
((RemoteMethodControl)originalProxy).setConstraints(localClientConstraints).equals(originalProxy) 
== false

If you break this contract the client might be vulnerable because it 
could easily confuse constrained and unconstrained proxies.

The solution is to have two objects with different identities:
- the proxy
- service identity (not to be confused with Registrar ServiceID)

The identity of the service could only be verified using service 
identity object:

// hypotthetical API
((RemoteMethodControl)originalProxy).getServiceIdentity().equals(((RemoteMethodControl)originalProxy).setConstraints(localClientConstraints).getServiceIdentity()) 
== true

My 2 cents :)

Thanks,
Michal

On 26/05/2020 10:10:50, "Peter Firmstone" <pe...@zeus.net.au> 
wrote:

>Hello River folk.
>
>As you are probably aware, I have an interest in security and have been focused on simplifying the use of secure services.
>
>In JGDMS the qa suite runs in jsse mode, which means the majority of tests are run with a login Subject and services use SSL/TLS Endpoints.
>
>A number of tests that passed with non secure Endpoint's failed with SSL/TLS Endpoints. Activation also failed, like the failing tests, it made assumptions on proxy identity.
>
>One of the problems I faced was proxy identity is defined by the underlying InvocationHandler's equals method, namely that of BasicObjectEndpoint.
>
>BasicObjectEndpoint was including the client's MethodConstraints in the Proxy's identity.
>
>This meant the service proxy's identity changed after the client applied constraints, and as a result, the tests weren't passing because the proxy's identity wasn't as expected.   Also Activation would fail as the ActivationID would be different.
>
>A code comment in placed in ActivatableInvocationHandler:activate0() method, for working around this issue.
>
>/* Equality of ActivationID instances are influenced by the
>          * equality of their Activator proxy's InvocationHandler,
>          * when client constraints differ, and everything else is
>          * identical, they will not be equal.  Proxy's deserialized
>          * by atomic input streams will inherit the constraints of
>          * the stream from which they were deserialized. */
>
>//        if (!id.equals(handler.id)) {
>         if (id.hashCode() != handler.getActivationID().hashCode()) { // Same UID.
>         StringBuilder sb = new StringBuilder(128);
>         sb.append("unexpected activation id: ")
>             .append(handler.getActivationID())
>             .append(" expected: ")
>             .append(id);
>         throw new ActivateFailedException(sb.toString());
>         }
>
>
>It got worse when I implemented AtomicILFactory, in Atomic streams, when proxy's are unmarshalled, they inherit any client constraints applied to the stream, to prevent elevation of privilege gadget attacks, where a third party proxy might bypass an integrity or privacy constraint for instance such as allow a connection that wasn't encrypted, or not authenticated.   Again this changed feature the identity of the proxy and tests failed as the proxy the test had to confirm the test passed didn't have client constraints applied.
>
>So it appears to me that client's MethodConstraints shouldn't be part of proxy identity.
>
>Does anyone have a good reason why client MethodConstraints should be part of proxy identity?   It doesn't seem right to me that the client is able to change the identity of a proxy, just by applying constraints.
>
>This seems to have been overlooked in the implementation.
>
>Also as a side note, I needed to make a lot of changes to existing services to support secure endpoints, as the server's often didn't reply to call back proxy's using their Subject, for example EventLIstener's didn't work in a secure environment.  I fixed that of course.
>
>These are changes I'd like to make to River, to make secure services behave like insecure services, but with security. :)  So that security can be a configuration concern.   So new developers can develop and test their application, later configure it to be secure without it breaking.
>
>Thanks,
>
>Peter.
>
>


Re: Proxy identity behaves unexpectedly for secure services.

Posted by Peter Firmstone <pe...@zeus.net.au>.
Thanks Michał,

I did consider that briefly, but then I realised there was no way to 
determine through equality what constraints had been applied and if 
unsure, the developer can apply constraints again.

It's a much bigger advantage to have equals working as expected.

Existing service utilities such as SDM apply the constraints for users, 
who can set them in their configuration.

Regards,

Peter.


On 6/6/2020 3:08 AM, Kłeczek, Michał wrote:
> Hi Peter,
>
> I think we need to be careful here - basically the semantics should be:
>
> MyServiceProxy originalProxy = ...
> MethodConstraints localClientConstraints = ...
>
> // THIS IS IMPORTANT!!!
> ((RemoteMethodControl)originalProxy).setConstraints(localClientConstraints).equals(originalProxy) 
> == false
>
> If you break this contract the client might be vulnerable because it 
> could easily confuse constrained and unconstrained proxies.
>
> The solution is to have two objects with different identities:
> - the proxy
> - service identity (not to be confused with Registrar ServiceID)
>
> The identity of the service could only be verified using service 
> identity object:
>
> // hypotthetical API
> ((RemoteMethodControl)originalProxy).getServiceIdentity().equals(((RemoteMethodControl)originalProxy).setConstraints(localClientConstraints).getServiceIdentity()) 
> == true
>
> My 2 cents :)
>
> Thanks,
> Michal
>
> On 26/05/2020 10:10:50, "Peter Firmstone" 
> <pe...@zeus.net.au> wrote:
>
>> Hello River folk.
>>
>> As you are probably aware, I have an interest in security and have 
>> been focused on simplifying the use of secure services.
>>
>> In JGDMS the qa suite runs in jsse mode, which means the majority of 
>> tests are run with a login Subject and services use SSL/TLS Endpoints.
>>
>> A number of tests that passed with non secure Endpoint's failed with 
>> SSL/TLS Endpoints. Activation also failed, like the failing tests, it 
>> made assumptions on proxy identity.
>>
>> One of the problems I faced was proxy identity is defined by the 
>> underlying InvocationHandler's equals method, namely that of 
>> BasicObjectEndpoint.
>>
>> BasicObjectEndpoint was including the client's MethodConstraints in 
>> the Proxy's identity.
>>
>> This meant the service proxy's identity changed after the client 
>> applied constraints, and as a result, the tests weren't passing 
>> because the proxy's identity wasn't as expected.   Also Activation 
>> would fail as the ActivationID would be different.
>>
>> A code comment in placed in ActivatableInvocationHandler:activate0() 
>> method, for working around this issue.
>>
>> /* Equality of ActivationID instances are influenced by the
>>          * equality of their Activator proxy's InvocationHandler,
>>          * when client constraints differ, and everything else is
>>          * identical, they will not be equal.  Proxy's deserialized
>>          * by atomic input streams will inherit the constraints of
>>          * the stream from which they were deserialized. */
>>
>> //        if (!id.equals(handler.id)) {
>>         if (id.hashCode() != handler.getActivationID().hashCode()) { 
>> // Same UID.
>>         StringBuilder sb = new StringBuilder(128);
>>         sb.append("unexpected activation id: ")
>>             .append(handler.getActivationID())
>>             .append(" expected: ")
>>             .append(id);
>>         throw new ActivateFailedException(sb.toString());
>>         }
>>
>>
>> It got worse when I implemented AtomicILFactory, in Atomic streams, 
>> when proxy's are unmarshalled, they inherit any client constraints 
>> applied to the stream, to prevent elevation of privilege gadget 
>> attacks, where a third party proxy might bypass an integrity or 
>> privacy constraint for instance such as allow a connection that 
>> wasn't encrypted, or not authenticated.   Again this changed feature 
>> the identity of the proxy and tests failed as the proxy the test had 
>> to confirm the test passed didn't have client constraints applied.
>>
>> So it appears to me that client's MethodConstraints shouldn't be part 
>> of proxy identity.
>>
>> Does anyone have a good reason why client MethodConstraints should be 
>> part of proxy identity?   It doesn't seem right to me that the client 
>> is able to change the identity of a proxy, just by applying constraints.
>>
>> This seems to have been overlooked in the implementation.
>>
>> Also as a side note, I needed to make a lot of changes to existing 
>> services to support secure endpoints, as the server's often didn't 
>> reply to call back proxy's using their Subject, for example 
>> EventLIstener's didn't work in a secure environment.  I fixed that of 
>> course.
>>
>> These are changes I'd like to make to River, to make secure services 
>> behave like insecure services, but with security. :) So that security 
>> can be a configuration concern.   So new developers can develop and 
>> test their application, later configure it to be secure without it 
>> breaking.
>>
>> Thanks,
>>
>> Peter.
>>
>>
>