[AFS3-std] Re: draft-wilkinson-afs3-rxgk-afs-01 comments

Benjamin Kaduk kaduk@MIT.EDU
Mon, 4 Mar 2013 12:27:15 -0500 (EST)


[digging up this old email from the archives since we referenced it 
recently]

On Thu, 7 Jun 2012, Simon Wilkinson wrote:

> Rather than reply point by point, I thought it might be helpful to clarify the security model that this draft is aiming for, and then we can address the best way of modifying the language in the draft to better communicate this.
>
> In a single user cache manager, we don't really care about the existence of the cache manager. Any data which is requested by a user is for the use of that user only. Similarly, any data returned by extended callback breaks is also only for that user's attention.
>
> In a multi user cache manager, on the other hand, data requests are on behalf of both the user (who will consume that data immediately), and the cache manager (which will store the returned data, and possibly supply it to other users). In this case, both are party to the initial request, and both have an interest in the validity of both the initial data set, and any data contained in later callback breaks. This is where the AFSCombineTokens operation comes in to play. It allows both the user, and the cache manager to authenticate both the request, and the response. Because the call is secured using a combination of the user and CM keys, the user can't forge fileserver responses in order to feed bogus data to the cache manager.
>
> For the purposes of this discussion, we are only interested in the security of extended callbacks. An attacker who can forge conventional callback breaks can only cause performance degradation to a client. An attacker who can forge extended callback breaks can insert arbitrary data into a clients cache. When talking about security, we are actually interested in two distinct properties. Firstly, it must be impossible for an attacker to forge callback breaks, and so corrupt the contents of the cache. Secondly, it must be impossible for an attacker to read callback breaks that are destined for another client. Extended callbacks may contain sensitive file, or directory information that shouldn't be disclosed to eavesdroppers.
>
> At the moment, clients are identified by means of either a UUID or a host/port pair. There's no cryptographically strong binding between the UUID and per-client-key. In a world in which all clients were centrally registered, we could create this binding by means of an identity (for example, each client has an afs-client/<hostname>@REALM Kerberos principal). However, we want to be able to support anonymous clients, so there's no need for central client registration. In this world, the only way in which a UUID and key can be associated together is through an assertion. In order to support truly anonymous schemes (where there isn't even a unique ID provided with each key), we're also not relying on individual cache manager identities.
>
> SetCallbackKey provides the mechanism for performing that assertion. However, because we have no trust in what has been asserted, we need to protect against two different scenarios. Firstly, an attacker that gets there before the current client, shouldn't be able to assert a key that then prevents a client from using extended callbacks. Secondly, an attacker who arrives after the current client shouldn't be able to assert a new key, and in doing so, gain the ability to read all of the client's outstanding callback breaks.
>
> The language contained in the draft was an attempt to balance these security requirements against implementation complexity.
>
> However, thinking about things further, I think there is an exploitable race between a client making a request, and an attacker performing a forged SetCallbackKey with the client's UUID. In order to prevent this race, we need to only permit anonymous identities with a unique (or hard to collide) identifier.
[The above background material included for completeness/preserving 
history]
>
> In this model, each time we receive a SetCallbackKey, we would record 
> the rxgk client identity which authenticated the RPC, and the key used. 
> We could maintain a LRU style list of these, up to some (implementation 
> defined) limit. When an identity is about to be removed for this list, 
> any callbacks held by that identity have to be transitioned to "normal" 
> callbacks.

My rough-sketch solution involved recording the CM uuid as well as the 
client identity (and key, of course) used to authenticate the 
SetCallBackKey RPC.

> Only RPCs which are authenticated with identities on this list would be 
> eligible for extended callbacks. RPCs with different client identities, 
> or which are issued over non-rxgk security classes, would not receive 
> extended callbacks. Where we have callbacks for the same object 
> requested by multiple different client identities, the key of the most 
> recent identity used would be used to encrypt the callback.

Hmm, I may be confused about what "client identities" means here.  All 
tokens are the result of the AFSCombineTokens operation, but we must 
consider at least ones with CM+user identity and just user identity.  The 
current text of the document (which has probably shaped my thinking) 
requires only that one of the identities used for a callback-generating 
RPC must match with the (single) identity used to perform SetCallBackKey. 
In this context, I'm not sure I understand what the last quoted sentence 
means.

> Making all of this work complicates things significantly at the client, 
> which must now maintain an rxgk token signing service, so that it can 
> issue a proper token to the server for each key that it has in play, 
> such that it can then pull the key out of that token.

But this makes it sound like maybe "client identities" means that we are 
requiring the full combined identity to match.

I will note for completeness (not sure if this is redundant given my 
imcomplete understanding of the above) that just using a single client 
identity (i.e., from a non-keyed CM) by itself to choose which callback 
key to use is insufficient, as a single client principal may be using 
multiple machines at once and generating callbacks.  So, the uuid or 
host/port pair must remain.

In any case, none of this has an obvious "AFSCombineTokens must change in 
this way" leaping out at me.

-Ben