2

I have been reading about JWT and I understand it has three parts namely, header, payload and signature.

I keep the hashing algorithm used in headers, basic information in a payload eg. name, age , role, expiry etc in payload and then both of these are base64 encoded and then hashed using the algorithm specified in headers to obtain the JWT

  1. I have a frontend where I can login using username and password.
  2. The login request goes to a server which authenticates it and returns a JWT. Lets suppose the algo used is HS256 which is a symmetric key algorithm.
  3. So the server will have the secret key using which the JWT will be generated.
  4. As part fo login request's response, the browser will have the JWT.
  5. Now this JWT could be tampered with on the way so before it is used, I should verify the authenticity of JWT.
  6. To verify, I need the secret key.

Questions:

  1. How do I get this secret key on the frontend?
  2. The payload can keep any information about a user (Not any sensitive information eg. passwords). Since JWT can be tampered with on the way, is it not dangerous to use the payload information without verifying the JWT on frontend?
Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82
Gaurav Kumar
  • 1,091
  • 13
  • 31
  • Depending on the language you're using, there are already plenty of fully tested and working JWT libraries available so you don't have to do this yourself by hand. – Morgan Aug 18 '18 at 14:34
  • @Morgan Can you point me to some link which tell how it does that. In any case, on frontend it will require secret key. I want to see how is that securely made available to frontend. – Gaurav Kumar Aug 18 '18 at 14:36
  • The site you linked to has a list of JWT decode libraries for various platforms. Check this https://stackoverflow.com/questions/38552003/how-to-decode-jwt-token-in-javascript to decode the token client side – Ash Aug 18 '18 at 14:45
  • @Ash I am not concerned about decoding. Its about how to verify the token on frontend – Gaurav Kumar Aug 18 '18 at 14:48

2 Answers2

5

The server which receives the JWT is the one who verifies the token. If someone modified the token, verification will fail and access will be denied, as (hopefully) no one outside the server knows the secret and therefore can't create a valid token. If the client knows the secret, esp. in browser/js envrinoments and with symetric hashing algorithmns, it's a big security risk and someone could steal the secret and create a new token with a valid signature.

jps
  • 20,041
  • 15
  • 75
  • 79
  • I totally agree with you that having the secret at the client side is a big security risk. So does that mean, whatever information is present in payload, I cannot use it on frontend? Because it might happen that while the JWT was sent to browser as a response, some malicious user intercepted the response and changed the payload. The only way I can make sure payload wasn't altered it verifying the JWT and I will require the secret key for that. In this case, the payload information that I use is incorrect. Hence it becomes mandatory that I verify authenticity of JWT. How could it be done. – Gaurav Kumar Aug 18 '18 at 14:42
  • 2
    That's one of the reasons why HTTPS should be used. And if you still feel the need to verify the token on your client, use an asymetric algorithm. Then you can verify with the public key, but only the server can create a valid token with the private key. – jps Aug 18 '18 at 14:46
  • 1
    whats the best practice. Is it not suggested to verify on frontend? – Gaurav Kumar Aug 18 '18 at 14:50
  • 1
    First, ask yourself: what damage could be done with a tampered token, which will fail verification as soon as a server side resource is requested? Which information in the token could be changed? Depending on your own judgment, you might consider using HTTPS and asymmetric keys. But there is no general best practice. But with HS256 or other symmetric algos, the best practice is to keep the key on the server. – jps Aug 18 '18 at 15:04
  • afai can think of, I can use the info from payload of tampered token to display it on UI which could mislead the user but the next request for protected resource with this tampered JWT would ofc fail so not much of a damage could be caused. If I am not using the payload info for anything then yeah no damage is done. – Gaurav Kumar Aug 19 '18 at 03:19
  • The UI code in the browser should just trust the claims of the JWT (username, scopes, etc) since everything in the browser can be tampered with anyway. The security risks should be on the server side, so it is the server (API) that needs to validate the claims of a JWT. – Peter J. Hart Sep 16 '20 at 15:52
3

Any bearer token should only be used over HTTPS. And TLS, which secures the HTTPS connection has integrity checks built in to prevent modification in transit.

So there's no need to verify the token on the client side.

Also it' better to treat the JWT token as some opaque string. This allows the issuing server to encrypt its content without breaking your application.

As others have pointed out, the client should never be in possession of the signing key, because the client can never be trusted.

Now, if the token is signed with an asymmetric key, you could download the public key and verify the token without compromising the security of the system. There are JavaScript libraries out there that can do this, but there's no reason you should be doing this.

MvdD
  • 22,082
  • 8
  • 65
  • 93
  • Yeah I agree. If the whole communication is happening over HTTPS then its secure and I can be sure that JWT is not tampered with. My doubt was regarding when the communication is not secured. So it makes sense that any Bearer token should be used on HTTPS only. I think I just wanted to hear this line. – Gaurav Kumar Aug 19 '18 at 03:23
  • That's why the OAuth2 RFC mandates the use of TLS, see https://tools.ietf.org/html/rfc6749#section-10.9. You can indicate you're satisfied with the answer by accepting it. – MvdD Aug 19 '18 at 05:01
  • @MvdD can you mention one of those client side libraries that can verify jwt? – Davorin Ruševljan Apr 25 '22 at 12:56