From: Tristan Tarrant <ttarrant(a)redhat.com>
Subject: Fwd: Re: Authentication implementation question
Date: 10 April 2013 14:49:51 BST
To: "infinispan-core-dev(a)infinispan.org"
<infinispan-core-dev(a)infinispan.org>
Hi guys,
I asked our Security Response Team for opinions on how a proper HotRod (or other types of
authentication, such as JGroups node-to-node auth) would need to be implemented without
incurring into common pitfalls.
The reply is below, and I'll soon be writing up a spec proposal.
Tristan
-------- Original Message --------
Subject: Re: Authentication implementation question
Date: Wed, 10 Apr 2013 15:22:01 +1000
From: David Jorm <djorm(a)redhat.com>
To: Tristan Tarrant <ttarrant(a)redhat.com>
CC: Arun Babu Neelicattu <abn(a)redhat.com>
Hi Tristan
Thanks for reaching out to ask us about this. It looks like the HotRod
protocol is stateless and designed for high performance, which makes
implementing a strong authentication mechanism a bit tricky. The #1
concern is mitigating replay attacks:
http://en.wikipedia.org/wiki/Replay_attack
If authentication credentials are just passed over the network in
cleartext, a man-in-the-middle attacker could extract them from a
message and attach them to their own malicious request. TLS/SSL
communication only partially mitigates this - when combined with other
flaws, replay attacks are still possible for encrypted communications (I
can explain this in more detail if required, but it is a bit of a
digression from the topic at hand). To mitigate this problem, you could
use a mechanism similar to HTTP digest authentication:
http://en.wikipedia.org/wiki/Digest_access_authentication
Since HotRod is stateless, you can't just authenticate the user once at
the start of a session and then leave the authenticated connection open.
Instead, you need to authenticate the user with each request. But since
you're designing for high performance, that would introduce too much
overhead, especially using a multi-step exchange like HTTP digest in
order to avoid replay attacks. So you could authenticate the user once,
then provide them with an authentication token that is valid for a given
period of time. All subsequent requests just have the authentication
token attached, which the server side can confirm is valid by
maintaining a cache. Once the token expires and is dropped from the
server-side cache, you authenticate again. This is the most efficient
approach, but it is still vulnerable to replay attacks - if a
man-in-the-middle can intercept an authenticated HotRod request, they
can extract the authentication token from it and attach it to their own
malicious request. This can be mitigated by selecting an appropriate
balance between the valid life of the authentication token and the
performance concerns. A token valid for 24 hours would make replay
attacks far too easy. A token valid for 1 minute would make replay
attacks very difficult, but could introduce too much overhead.
The alternative approach is to make the protocol stateful. Then you'd
just authenticate once at the start of the session (using something like
digest to avoid replay attacks), and avoid the need for tokens.
In addition, I have the following recommendations:
* Default to authentication over TLS/SSL if at all possible
* Do not implement account lockout for too many incorrect password
attempts as this becomes a vector for denial-of-service attacks
(intentionally lock out someone's account using invalid login attempts)
* On the server side, only store salted one-way cryptographic hashes of
credentials, no passwords either cleartext or encrypted
I hope that helps, please let me know if I can be of any further assistance.
Thanks
David