Instead of putting the proxy in the String annotation, can it go in an additional byte array in MarshalledInstance?

This can be used by a trusted lookup service proxy to perform trust operations on behalf of the client.

During marshalling, if the first Proxy implementing ProxyTrust found in the stream could be replaced by a token, then serialized into another array. During unmarshalling, the Proxy would be restricted to the trusted classes required for proxy verification. Because these are trusted local classes the proxy doesn't require any annotation to be unmarshalled.

The proxy could also implement another interface, which after verifying it's a trusted object and applying constraints, could be requested to provide an array string of all classes it wishes to unmarshall. Now since we trust the proxy and have authenticated, we're now preventing a third party that may have intercepted the stream, from doing harm.

In addition we might ask the proxy for Certificate signers for the codebase. We could even ask it for the codebase annotation, if we wanted.

At this point the bootstrap proxy is trusted, so we're ready to unmarshall a smart proxy, if it exists and replace the token that was inserted during marshalling, with the bootstrap proxy.

Unmarshalling this remote object we could ensure the jar file is signed by the correct Certificates, and restrict unmarshalling to the list of classes supplied by the bootstrap proxy.

After unmarshalling we could apply constraints to the smart proxy and return a fully prepared proxy to the client, resulting in simpler client code.

Regards,

Peter.


Peter Firmstone wrote:


On 3/05/2013 12:22 AM, Michal Kleczek wrote:
So the problems to solve are:
1. Possible buffer overflow and DoS type of attacks - since we do not authenticate the stream before deserialization of the first object an attacker can possibly inject huge objects (of classes available locally) in the stream (such as LinkedList of arbitrary size). 2. Leverage of vulnerabilities in classes available locally during object deserialization.

Limiting the list of classes that can be instantiated before doing codebase verification is a good idea that could possibly solve both issues. That would be basically providing a small Trusted Computing Base for security checking of downloaded code. But that actually means that codebase annotations _should_ be objects that implement their deserialization in a secure manner so that attacks from point 1. are not possible. As of today we use java.lang.String which does not put any constraints on its size.

Objects themselves have no way of limiting the size of the stream transferred, unless they only read a limited number of bytes and avoid calling readObject() on the stream, but that's very restrictive and this would place an unnecessary implementation burden on our trusted computing base, which would have to be careful not to download excessive bytes too.

We need to limit the bytes read from the stream until trust is verified, we could do that by wrapping the InputStream passed to the MarshalInputStream constructor and counting the bytes read until we reach our limit, resulting in an IOException and closing the stream, otherwise the proxy is verified and we set a boolean value to stop counting prior to reaching the limit.

So we are very close to the solution, but I don't feel that ah-ha moment yet. I'm off to bed now to sleep on it.

Cheers,

Peter.


To provide backward compatibility we could fall back to old implementation in case the class is not part of TCB. We would only allow it if the stream is authenticated beforehand.

Michal

On 2013-05-02 15:35, Peter Firmstone wrote:
On 2/05/2013 9:32 PM, Michal Kleczek wrote:

An attacker can use a serialization attack, without requiring jini, to create a ClassLoader and start downloading classes out of band.

Given you never execute untrusted code: how?


I'm glad you asked me this question, because I just stumbled over a partial solution:

http://www.ibm.com/developerworks/library/se-lookahead/index.html

Ironically I went looking for an example on the web for you, but this article instead, completely unexpected, this article is very good because it describes the issues with serialization well. The article was only written in January this year.

Just possibly we could restrict the classes that MarshaledInputStream can instantiate to only those required to perform proxy verification.

Could we limit both the bytes read from the stream and the classes (required for connection and proxy trust) deserialized from the stream until proxy verification has been performed?

The challenge is, how can we do this and retain backward compatibility in marshalled object streams?

If there's an answer to those questions, it's the security grail for Jini the Sun team was looking for.

Cheers,

Peter.







Reply via email to