Security Consideration: Derivation of Stolen Tokens
jricher opened this issue · 4 comments
If an RS is able to get a hold of a stolen token, and that RS is allowed to get derived tokens from the AS, then the RS will be able to derive the rights of the token through that call. The AS prevents this by requiring the RS to authenticate itself during this request, but this needs to be spelled out in the security considerations.
(credit to @pq2 for reporting)
I am not quite sure how this prevention is supposed to work. Does the AS only allow certain RSs to use token derivation and it is assumed that all RSs that are allowed to do so are honest? Or can only a certain RS derive a new access token from a certain access token, so the AS effectively binds the access token used for derivation to an RS?
The latter possibility would arguably be more effective for preventing the attack, since it does not assume that all RSs used are honest. However, this possibility assumes that the AS knows in advance which RS will use the access token for token derivation, and I don't know how feasible that is.
Yes, the AS shouldn't allow just any RS to do token derivation to begin with. Plus, I personally don't picture it as binding the RS to a specific access token, but more like binding classes of access tokens.
So let's say you get an RST that does page translation with a "translate" access right. That RST needs to call another RSD to get the domain-specific dictionary, with the "dictionary" right. The client gets a token for "translate" to call RST. RST then turns around to the AS and asks for a token to do "dictionary" at RSD. The AS would know, from configuration, that RST is allowed to trade "translate" tokens for "dictionary" tokens, in the context of the original "translate" token. This context could include which user OK'd it (and so which dictionary to pull), which languages are available, etc. The AS doesn't need to specifically tie the original token to RST in order to know that RST is allowed to make that very specific trade. If RST is compromised, it can still trade any "translate" token for a corresponding "dictionary" token, but that is exactly it's job and GNAP can't detect or prevent that since the behavior is indistinguishable from RST behaving as intended.
+1 to @pq2 on binding to a specific RS. If you want a policy that doesn't distinguish between RS's within a certain "class" (translators vs. dictionaries), that's fine. But we should also support a policy where the RS needs to prove that the token was indeed issued to it. I would add something like:
The AS MUST validate that the received existing token is valid, and MAY also validate that it was issued to the RS that presents it.
The sentiment makes sense -- the language needs some tweaks to be accurate as to what's happening, because it's more about making sure the token was issued with the RS as its audience (or one of its audiences). You don't expect the RS to be the original carrier of the token, that's the client.