JWT Considered Harmful

selective focus photography of yellow padlock

Recent brush with a program written by a self made JWT evangelist has filled me with rage. Few months ago when we spoke of the same topic, I could not fathom why he was so excited by this technology. After reading the program, I understood that he completely missed the point.

I believe two things need to put as disclaimer everywhere JWT is mentioned:

First, JWT does not encrypt data.

The programmer had to do email validation prior to an unauthenticated action. The programmer received a request with an email address. He then responded to the request with a JWT token and sent a verification code to the email address  The user then had to send a second request with the returned token and the verification code to proceed. The task is simple enough. Except, he returned a JWT signature as his registration token. He put in the entire registration request as well as the code to be verified in the signature.

Why did he do it? My guess is that he did not want to create another database table or use a cache to store the temporary registration data. Or maybe thought he had discovered the new holy grail of data encryption. He also missed the memo: JWT does not encrypt data.

Beside all the ifs and whens of when the JWT secret is compromised, JWT is designed for just one thing: prevent short term data tampering. JWT signed tokens may look like encrypted data. However, it is just three JSON documents, base64 encoded and concatenated together with a period (.). First document specifies which signing algorithm is used. Second document specifies the entire input payload. And the last document contains the signature. It is probably base64 encoded only for the purpose of easy splitting as period is not one of the 64 characters used in this encoding.

This email verification could be easily hacked by base64 decoding the payload. It is a good thing we didn't release this API.

Second: JWT does not remove the need to re-verify requests.

Another horrible way I've seen JWT used is to store partial verification/validation state. A request would be sent. It would be verified and "encrypted" as a token. This token would be returned to the user or put in a data store. Subsequent requests would assume that the signed data valid.

I believe the terms he used was: 'It is cool. It is like how accounting/legal documents are signed.'

Well, it is not cool. What if the request is no longer valid? State of the system could have changed in the time, making the request no longer valid. And of course, the JWT secret could have been compromised - it was just an easy to guess static hard coded value in the code.

I am not saying JWT is useless. It has its uses and it can be used properly for its uses. For example, a  college used it to sign chat messages for a remote medical consultation app. A JWT secret was used during chat session initiation and subsequent messages were sent signed using that secret. I've used it to sign web-hook event notification callbacks to insecure endpoints.

In summary, don't use JWT as the holy grail for security. If the intent is to not expose data, don't send it over the wire. If you have to, use secure transport and/or proper encryption algorithms. Don't rely on it to not need re-validate requests as they may have become invalid.

Comments