26

I am a complete noob when it comes to security, authentication strategies. So I was reading this article about "Token Based Authentication": https://scotch.io/tutorials/the-ins-and-outs-of-token-based-authentication

I have 2 questions:

  1. I don't understand why a middleman(or a hacker) would not be able to see the token being sent by the client and use the same to impersonate as that client/person to retrieve resources? What makes JSON Web Tokens / OAuth2 based authentications safer in that sense? If we use a onetime-use-only token every time, I would understand that even if the hacker can read the token he will not be able to use it for another request. But as the token stays the same until it expires, how is that a safer authentication strategy?

  2. How does the server know that the token sent by the client is valid i.e something that the server exchanged with the client during login. Does the server store the token generated in a database or somewhere and keep updating the "last accessed timestamp" or something and keeps removing the tokens where last_accessed_time is > 1hour ago, to keep expiring it after 1 hour of inactivity?

Cœur
  • 37,241
  • 25
  • 195
  • 267
user1102532
  • 495
  • 6
  • 16

2 Answers2

34

I don't understand why a middleman (or a hacker) would not be able to see the token being sent by the client and use the same to impersonate as that client/person to retrieve resources?

JWT does not protect you to a man-in-the-middle (MITM) attack. If an attacker gets a valid token, can effectively impersonate. Even if the content is encrypted.

JWT should be used with a SSL/TLS connection to avoid MITM

What makes JSON Web Tokens / OAuth2 based authentications safer in that sense?

JWT is a token format, and oauth2 is a protocol. oauth2 can use jwt. Oauth2 is safer to the user using a third party site because credentials are only sent from the user to the main site, then the site issues a token that can be used by the third party site to authenticate user. The third party site never see the user credentials

But as the token stays the same until it expires, how is that a safer authentication strategy?

Read above. You need to protect your tokens to not be stolen: Mainly use HTTPS, or mitigate its effects: store in cookies with HttpOnly (if you do not need to access JWT content in client side), set expiration time short, rotate tokens...

How does the server know that the token sent by the client is valid i.e something that the server exchanged with the client during login.

The third part of a JWT like hhhh.pppp.ssss is the signature. The signature is performed with server private key over the header and payload (hhhh.pppp), an protects the content. If an attacker alters the content or the signature, the server will detect it verifying the signature and will reject the authentication.

Does the server store the token generated in a database or somewhere and keep updating the "last accessed timestamp" or something and keeps removing the tokens where last_accessed_time is > 1 hour ago, to keep expiring it after 1 hour of inactivity?

It is not needed. The signature is packed in the token itself (ssss), therefore it is said that JWT is self-contained

The server has a cryptographic secret key or a key pair, public and private. The token is signed and verified with the secret key (for HMAC symmetric keys), or signed with the private key and verified with the corresponding public key (for RSA asymmetric keys).

Cœur
  • 37,241
  • 25
  • 195
  • 267
pedrofb
  • 37,271
  • 5
  • 94
  • 142
  • Awesome explanations. – user1102532 Jul 27 '16 at 17:32
  • I was able to implement this and it works well, but there's another thing that I am not sure of.. We create a token and say we set it to expire in 15 mins. It expires in 15 mins no matter what and the user needs to authenticate again. What I want however is to refresh this token as long as the user is active and expire it only when he/she becomes inactive for 15 mins. How can we accomplish this as the token is stored at the client side and even if we alter the expiration timestamp by decoding the base64 token and encoding it back again will not work. – user1102532 Jul 27 '16 at 17:40
  • 1
    You can't modify the expiration time of JWT because it will break the signature and server will reject the token. You have to renew the token when it is close to expire. For example, when responding a request, do the server issue a new JWT and set a custom header in response. Alternatively perform an specific AJAX request from client to get a new token – pedrofb Jul 27 '16 at 19:17
  • Check also this post with recommentations about how to refresh tokens http://stackoverflow.com/questions/26739167/jwt-json-web-token-automatic-prolongation-of-expiration/26834685#26834685 – pedrofb Jul 28 '16 at 14:53
  • How to invalidate tokens when user logs out or changes password without also storing them in a database? – One-One Oct 17 '17 at 04:28
  • 1
    @One-One, take a look here to see some common techniques https://stackoverflow.com/a/37520125/6371459 – pedrofb Oct 17 '17 at 07:23
1

It is all about signing the token not encrypting the token. The server just verifies the signature, JWT is not encrypted (unless you implement it). Dont store sensitive data in the token, cause it is not encrypted by default.

giannis christofakis
  • 8,201
  • 4
  • 54
  • 65
Amir Sasson
  • 10,985
  • 1
  • 13
  • 25
  • 1
    Does this signature change for every user and for every different login of the same user ? If so where does the server store these signatures in order to check whether an incoming request is valid ? – user1102532 Jul 26 '16 at 19:25
  • you can consider the signature as an encrypted checksum of the actual token. of course each token is different, so the signature is different. the server just have the private/public key that used to sign the token. when receiving a token, the server just validate that the token is genuine by matching the token with is signature. Man in the middle attack (if not using https) can change the token, but he cannot know the keys that used to sign the token, so the server would identify the token as not genuine, and will fail the call – Amir Sasson Jul 27 '16 at 03:16