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.