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.