5

I am currently building a RESTful API that will be used for a web and mobile app. Authentication to the API will be done using JSON Web Tokens.

When using JWT, we can use the exp claim to expire the token after a specific time. This, combined with the jti claim is useful to prevent replay attacks, and something that will be built in to our app. However, for user convenience, we do not want to keep asking them to log in with every request or after short intervals of say, 30 minutes.

So, I'm thinking of the following situation:

  • User logs in using their email address and password
  • Server sends back a JWT with an expiry in 1 hour
  • The client makes another request to the API, passing the JWT in the header
  • If the JWT is valid, the API sends back the requested data, and another JWT, which again expires in 1 hour

If the client does not make any further requests within the allocated 1 hour expiration time, a subsequent request would ask them to log in again.

My question: is this the best solution trade off between usability and preventing replay attacks?

BenM
  • 153
  • 1
  • 4
  • 2
    Wouldn’t you use TLS on the transport anyway? What threat model do you try to defend against? A network based adversary couldn’t replay a sniffer TLS session. – Tobi Nary Nov 27 '17 at 16:23
  • Yes, TLS will be used, but ultimately the token will be stored in a session on the client (JS), so the threat we need to mitigate is an attacker accessing the token, and preventing it from being used. – BenM Nov 27 '17 at 16:26
  • 1
    And if an attacker does manage to get a token, what's to prevent them from requesting a new one every hour? – AndrolGenhald Nov 27 '17 at 16:28
  • @AndrolGenhald they would have to access it within a very small window of issue (i.e. before the expiry time, and before the genuine client has made a request using it; notice the use of the `jti` claim). – BenM Nov 27 '17 at 16:29

1 Answers1

6

I think you need to separate you concerns. Protecting the JWT on the client side is the job of the application using the JWT, not the API. If this line is blurred than you may need to re-engineer you application as it's probably more monolithic, rather than service driven.

JTI, EXP and IAT are designed more to give you the tools to mitigate an attack if it's been compromised. TLS is used to prevent snooping of the JWT while in transit. Shortening the window for the EXP will limit the exposure of the single token, but ultimately if they got the token via the application, the EXP is mute, they'll just grab the next token.

Shane Andrie
  • 3,780
  • 1
  • 13
  • 16