Archive
Do web tokens actually make us safer?
There has been a lot of science that goes into making the web a safe place to do commerce with your desktop computer thanks to Netscape when they created Secure Socket Layers (SSL – 1994). In 2007 we entered the world of the Smartphone thanks in part to Apple (we should leave ‘Simon – 1992’ out of this discussion). It wasn’t until 2015 when the IETF released its vision for sessionless tokens that we found another way to manage a session but is this really more secure?
Current technology utilizes cookies that manage the ‘state’ of your connection in order to prevent you from having to login every time you press a button (imagine how painful that would have been?). We have created many controls that help protect cookies curing transmission and at rest but it still requires users to login to obtain a valid session cookie every time. Mobile users would not be happy so we needed a better solution.
Browser -----------(send login request) ---------------> Server < -----------(send cookie) -------------------- (create session) ----------------(sends authentication) --------> (validate) <-------------------(send response) -----------
A JSON Web token is similar to a session cookie and in order to protect them, we decided to create three types of security with it. First option is no security at all (null) and there is nothing secure about that right? These were created to manage other types of data exchange where other security controls were used.
The second type can use a signature to be sure that it cannot be modified. (There is also a third type that uses public key encryption and is preferred but can add significant overhead to the developer and is not widely adopted yet). Lets focus on the second type.
Browser -----------(send login request) ---------------> Server (first use) <---------(send JWT) -------------------- (create JWT) (if exist) -------------(sends authentication) -------> (validate sig) <-------------------(send response) ----------- (valid user)
Ensuring the integrity of the message can be done by signing the JWT with a message authentication hash which can be created by adding up all the data and hashing it with a secret passphrase. If the developer does not use a strong passphrase and we can guess it, an attacker (that’s me!) can modify the message. Cracking that hash and determining the secret that was used is a lot like guessing what password you use to login. We can use the same method we use to crack your password to determine what secret was used to create the hash for your signature!

Cracking JWT using hashcat with 4 GPU
For a mere 3,000 dollars, I built a computer that can guess the secret that was used to create the hash at speeds of 250 million guesses per second. If the developer does not choose a good long password, they cannot expect to have a high level of trust that users are, who they think they are, when they login.
Now, because the token is transmitted to the client and then accepted whenever the connection is made, the server has no way of knowing that I am not you (after I capture your token or after I compromise your device and steal the token). Using tokens that live on the (untrusted) client is far riskier that using cookies that are stored on your (supposedly secure) server.
Don’t get me wrong, I think the advantages of tokens over cookies helps offset the risk but my lesson here is that we must ensure the integrity of our security controls when it comes to using JWT. They solve many problems that traditional session management has including;
- cookies can be disabled (such as 3rd party cookies across domains)
- cookies are per device whereas tokens can work between your desktop and your mobile device to create a seamless experience
- memory issues server side for cookies but tokens reside on the client
With great power comes great responsibility so we must take additional steps when deciding to use tokens in place of cookies. Our infrastructure will be slow to provide protection for these as they did for cookies so the responsibility is on the app developer to use strong passphrases and to implement encryption when using sensitive claims with the tokens.
In short, if you read the RFC for JWT, you will find the following statement;
The contents of a JWT cannot be relied upon in a trust decision unless its contents have been cryptographically secured and bound to the context necessary for the trust decision. In particular, the key(s) used to sign and/or encrypt the JWT will typically need to verifiably be under the control of the party identified as the issuer of the JWT.
This means that your developers must be following best practices when choosing their pass phrases. A good rule of thumb is to use one bit of entropy for every byte data you wish to protect. If you are using 256 bytes of a payload you should consider making your pass phrase, 32 bytes long. You should also carefully consider ‘pass phrase/key’ rotation and token expiry policies. Session hijacking is one of the most important tools in the hackers toolbox and is easily executed if session management is not done right!