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" <peter.firmst...@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.



Reply via email to