Should we try to avoid reuse of useDevconTicket

Discord said this discussion is too long to fit a chat message and I think it should be discussed in a thread so here it is. @jot2re said:

The reason this is an issue is that there is nothing build-in to useDevconTicket that ensure that it has been constructed freshly for its current use and thus it can be replayed. I am aware that we want to prevent this through what org.tokenscript.auth verifies, but this does not prevent copying the useDevconTicket since the proof of knowledge within the useDevconTicket can be reused since there is no linking to the current usage. My suggestion is simply to allow the challenge without the Proof of Knowledge to take an auxiliary argument that can be used to link it to its specific usage. This auxiliary info can then be stored as part of useDevconTicket and can either be the identity of a smart contract or a website domain concatenated with a timestamp or some other challenge.

Hi @jot2re#9588 I thought we have given up making sure useDevconTicket is fresh because the person who wish to authenticate against a website can always get a copy from a smart contract call which the ticket holder made in the past. As of your suggestion, I'm confused as to what it means.

My guess is you mean this:

π‘Ž) to allow the-challenge-without-the-Proof-of-Knowledge to take an auxiliary argument that can be used to link it to its specific usage.

That is, the challenge is issued without the consideration of the PoK, for example, the challenge is the hash of Ethereum Signed Message:\

𝑏) to allow the response to the challenge not to contain the PoK.

Which one is what you are after?

If π‘Ž: I have considered π‘Ž in the past TS design sessions, the reason is to prevent man-in-the-middle attack‑ and we previously (I believe) discussed methods such as using a derived key (derivated by the website's domain name) or ask proof of knowledge of the private key should user wallet support such use (or both). We can implement such a challenge prefix (website domain), be aware that against our wish, we reduced Authenticator to a utility that provides the useDevconTicket for either using in a transaction or web authentication, leaving Webster (i.e. web developer) to decide how to form JWT and parse it from their server end, so the said change would be purely in the Webster's space and not affecting @olehhrib's library.

‑ The website instead of sending genuine challenge, forwards challenges from a malicious source. this allows the man-in-the-middle to authenticate against a website that the ticket holder doesn't intend to use, by setting up a website and phishing the user into authenticating against it.

Just to recap what we said about this in the TokenScript design meeting: Basically my suggestion was to make every Proof of Knowledge unique to the context where it is to be used by letting the randomness within the PoK be derived from a challenge for that usage (e.g. a timestamp and a domain name of the receiver). As you mention, if a malicious website can inject a malicious challenge to get signed by the user then we have a man-in-the-middle attack. But the user necessarily needs to sign something at some point to prove they are who they claim. This will also have to be unique for the usage, otherwise any malicious site that manages to learn useDevconTicket object be able to reuse it.

The goal of my suggestion was not to achieve neither a nor b, but simply to have a stronger linking between the usage and the proof. The reason being that now the proof only says "at some point in time the real user constructed a proof for some usage". It does not say anything about whether it is the current usage. However as Oleg also mentioned, this does not directly allow for an attack since the specific usage contains the proof and is signed with the user's key. But when there is no linking it basically make the usage of PoK meaningless since we must assume that an adversary can easily intercept it. By including the challenge in the PoK we get a conceptually stronger linking since now the proof shows "the user constructed the proof right now for usage at this specific website".

Again, I cannot see any direct attack with the current approach (but that does not mean that there can't be one). My point is that from a conceptual and cryptographic design point of view, we want the challenge to be part of the proof. Even if there is no possibility for attack now, doing so increases the robustness and could prevent attacks potentially caused by coding errors. Furthermore by keeping the design as cryptographically strong as possible, it also increases the chance that the full protocol can be formally be proven secure (if we ever wish to go upon that endeavour).

We decided at the meeting that this is not high priority now and we may revisit this in the future after the have an MVP