Common JWT security vulnerabilities and how to prevent them

The JSON Web Token has received a number of security reviews at the IETF and OIDF and is deemed sufficiently secure by experts. But this doesn't make it foolproof. You, as a developer, can easily shoot yourself in the foot by making inappropriate use of JWT or a library that implements it, including this one.

Received JWTs must always be validated. When you do that, never ever let the JWT or any of its header parameters drive the verification process alone. Always have a clear cut contract in place, tailored to your application, stipulating the permitted JWT algorithm and other header / payload / claim parameters.

Do not attempt to cryptographically process a JWT before this initial screening passes. If you receive a JWT with an unexpected algorithm, type header, etc, discard it, and stop right there.

Remember that JWTs can come in as HMAC protected, signed, encrypted, or even completely unsecured (alg = none). That a JWT parses and has the correct format does not mean that it can be trusted. The most blatant way to make your app vulnerable is to get the alg header, and then immediately proceed to verify the JWT's HMAC or signature, without first checking if that JWT alg is permitted. What will happen to your app if it gets an unsecured JWT with alg = none?

Remember, always have a clear cut contract in place, and use it to screen each JWT before attempting to decrypt it, or check its signature or HMAC.

OpenID Connect relying parties for instance establish the permitted ID token security algorithms at registration time. ID tokens that don't match the expected algorithm get discarded on the spot.

Example ID token contract:

  "id_token_signed_response_alg"    : "RS256",
  "id_token_encrypted_response_alg" : "RSA-OAEP",
  "id_token_encrypted_response_enc" : "A128GCM"

OpenID Connect further specifies where the RSA or EC keys to validate an ID token can come from: the IdP's published JWK set URL, and nowhere else. Which key to use, if multiple are published at the JWK set URL? This is communicated by the kid (key ID) header parameter of the JWT.

  "alg" : "RS256",
  "kid" : "sho0jea6"

If you're validating ID tokens, use a well-tested and established library, such as our OAuth 2.0 and OpenID Connect SDK. You can also use a security framework integrates our SDK, such as Spring Security and Pac4j.

If you're going to validate JWTs as OAuth 2.0 access tokens - check out the example here. It demonstrates usage of the Nimbus JOSE+JWT framework for processing JWTs that takes into account all of the above.

2. Know the algorithms

Know your algorithms, and what security properties you can expect from them in terms of integrity, authenticity, non-repudiation and confidentiality.

A common mistake is equating Hash-based Message Authentication Codes (HMAC) with digital signatures. No, they are not the same, even though they use a common format (JSON Web Signature). Remember that the JWS format is also used for unsecured (alg = none) JWTs.

This library will not allow you to confuse unsecured JWTs with HMAC or digital signature protected JWTs, because it uses separate Java types for them. But other libraries may not enforce this. We have found that OOP and type safety are generally good for security.

If you're wondering what particular JWS or JWE algorithm to use for your app, check out our algorithm selection guide.

3. Use an appropriate key size

Make sure you use an appropriate key size for your application.

This library has a number of checks in place prevent usage of HMAC keys shorter than 256 bits, AES keys shorter than 128 bits, or RSA keys shorter than 2048 bits. Beware that other libs may not enforce such checks.

Finally, remember to take all necessary measures to keep your shared or private keys secure. The Nimbus JOSE+JWT has support for plugging in a Hardware Security Module (HSM), a piece of hardware that performs signing or encryption in a external device while keeping the keys inaccessible from the OS and software.

4. Study the Best Current Practises RFC

The OAuth working group has put together an excellent JWT best current practices (RFC 8725). It enumerates known threats and vulnerabilities and suggests 12 measures for dealing securely with JWTs. Check it out!

comments powered by Disqus