JWT handling best practices - Avatao (2024)

JWT, short for JSON web tokens, is a popular method for managing user authorization and authentication in web applications. It is designed for allowing parties to transmit information securely. JWT is a good choice when implementing custom security mechanisms in applications because, in addition to the security, almost every popular technology provides support for JWTs.

JWT structure

A properly generated JWT consists of three parts: Header, Payload, and Signature. These three parts are encoded separately using Base64url, and each is concatenated to the other using periods to create the token.

This is what an encoded JWT string looks like:

eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFzZCIsImFkbWluIjp0cnVlfQ.HGcvua9PvrK-xq1_ed4GoCrXYrKkGgGKqvpXk94fKoo

This resulting token can easily be passed into HTTP and HTML.

Header

The JWT Header contains information about the type of the token and about the cryptographic algorithm used to generate the signature. An example is shown below:

{
“alg”: “HS256”,
“typ”: “JWT”
}

The “typ” field defines the token type. If it exists, it must be set to a registered IANA Media Type. The “alg” field represents the message authentication code algorithm. This algorithm can be set freely, but it’s important to note that some of the supported algorithms are not secure. In this example, the chosen algorithm is HMAC with SHA-256.

Payload

The JWT Payload contains a set of claims which can be standard or custom properties. The seven standard fields are defined in the JWT specification. For example:

  • iss – Issuer: describes the issuer
  • aud – Audience: the actual recipients
  • exp – Expiration Time: defines the valid time interval for accepting the JWT
  • sub – Subject: JWT subject

Depending on the functionality of the token, custom fields are also an option in the Payload.

{
“username”: “john”,
“admin”: “false”
“exp”: 1548632574
}

In this example, username and admin are custom fields, while exp is a standard field.

Signature

The Signature is responsible for secure validation of the token. It uses Base64url Encoding to convert the Header and Payload, and the results are concatenated by a period separator. After the procedure, the completed string runs through the defined algorithm from the Header, which is “HS256” in the previous example.

The attack in practice:

The following Ruby code is a simple file opener/reader.

HMACSHA256(

base64UrlEncode(header) + “.” +

base64UrlEncode(payload),

secret)

How does JWT work?

During the authentication process, after the user has successfully logged in, the returned JWT will be stored locally. Session storage is used for this in most cases, but cookies are also a viable option. But it’s not just the server which can generate a JWT – if the requirements meet the appropriate standards, the client is also allowed to generate its own JWT. The JWT must contain a pre-shared secret which needs to be passed towards an OAuth compatible service. The server then checks the generated JWT and if it is valid, an access token will be generated by the server and sent back to the client. If the client would like to communicate with the server through protected routes, the JWT needs to be forwarded because these routes check for valid tokens in the Authorization header. On the client side, the user agent is responsible for attaching the JWT in the Authorization header using the Bearer schema. If the JWT is in its place, the client is able to access the protected data.

When and why use JWT

Using JWT tokens by default is not a good idea. Due to its complexity, there is a higher possibility of security mistakes occurring. The amount of data being carried is also increased. Each request contains a ton of overhead. One pro of using JWT is that the server does not need to use a database to store information about the client, because it is already stored in the JWT. So overall, for implementing API authentication and server-to-server authorization, JWT can be a very useful technology depending on the intensity of the communication between the server and client.

Security concerns (basic misconfigurations, most common security pitfalls and mistakes)

Because JWT is an authentication and authorization related technology, the impact of failures and security vulnerabilities can be quite critical. The IT community has collected a large number of common security pitfalls for JWT. JWT implementation mistakes could lead to very severe security issues. The most common ones are below:

Improper JWT Validation

There are many ways in which JWT validation can be broken during implementation. The most typical are listed below:

Missing validation of the Signature:
The JWT payload is decoded despite the JWT token being invalid because the signature was never validated.

Missing validation because the None alg is provided:
It is possible to create a token by setting the JWT algorithm to “None”. The server has to check that the “None” algorithm was implemented during the JWT creation process. Regardless, each JWT with the “None” value in the “alg” field will be managed as a valid token.

Changing from RS256 to HS256:
The RS256 uses different keys for signing and validation – that is, a public key and a private key. HS256, on the other hand, uses the same key for the same process. This means an attacker could create the token by setting the signing algorithm to HS256 instead of RS256, which results in the API blindly verifying the token using the HS256 algorithm, using the public key as a secret key.

Safe secret key creation

The secret key must be a complex character combination. This ensures the key will be unpredictable and safe. Developers often use copy-paste coding, and while this can be effective, its downside is that developers can be inattentive and forget to reimplement the necessary functions and reset the original parameters. This can occur during the implementation of JWT when the developers use a template code and leave a static simple string as the secret key instead of generating a random one. A brute force attack can very effectively exploit this vulnerability.

Setting JWT as a session cookie

There are situations where the JWT needs to be revoked, such as the log out process. The server should invalidate the token, but it is impossible because the JWT is stored on the client side, and the server does not know which JWT should be revoked. Storing the linked user token pairs in a database on the server is also an option, but this is not what the JWT is designed for.

Accidentally revealing the secret key

JWTs are created by private secret keys. The key is a critical factor in the process and it needs to be hidden from the public as much as possible. Sadly, developers sometimes make mistakes and leak the secret key by storing it on the client side javascript code or in publicly accessible files. If this happens, an attacker can break the signature verification with ease. From this point, the attacker can sign any payloads with the secret key and trick the signature validation on the server side.

Summary

A correctly implemented JWT can help with authorization, authentication, and transferring data between parties, but it is not always the best or most effective solution. Using JWT is a choice between security and performance, and deciding between them depends on the purpose. If you need to use JWT, then make sure the implementation is properly realized to avoid the possible security pitfalls and protect the application as much as possible.

JWT handling best practices - Avatao (2024)

FAQs

What are the best practices to store JWT? ›

To keep them secure, you should always store JWTs inside an HttpOnly cookie. This is a special kind of cookie that's only sent in HTTP requests to the server. It's never accessible (both for reading and writing) from JavaScript running in the browser.

What is the best practice for JWT duration? ›

JWTs are self-contained, by-value tokens and it is very hard to revoke them, once issued and delivered to the recipient. Because of that, you should use as short an expiration time for your tokens as possible — minutes or hours at maximum. You should avoid giving your tokens expiration times in days or months.

Is it good practice to store JWT token in local storage? ›

Best practices for storing and sending JWT tokens in the browser include secure storage in localStorage or sessionStorage, serving over HTTPS, using HttpOnly cookies, implementing token expiration and refresh mechanisms, CSRF protection, and token revocation mechanisms.

What do you need to decode a JWT? ›

By design, anyone can decode a JWT and read the contents of the header and payload sections. However, we need access to the secret key used to create the signature to verify a token's integrity.

How do I keep my JWT token safe? ›

Best Practices for JWT Implementation
  1. Secure Storage: Store JWTs in HTTP-only cookies to prevent access from JavaScript, reducing the risk of XSS attacks.
  2. Token Expiration: Set a reasonable expiration time on JWTs to limit the time window for potential misuse.
Jul 27, 2023

How big is too big for a JWT? ›

Avoid putting unused claims into a JWT. While there is no limit to the size of a JWT, in general the larger they are, the more CPU is required to sign and verify them and the more time it takes to transport them. Benchmark expected JWTs to have an understanding of the performance characteristics.

How long should a JWT token last? ›

When using the Org Authorization Server, the lifetime of the JSON Web Tokens (JWT) is hard-coded to the following values: ID Token: 60 minutes. Access Token: 60 minutes. Refresh Token: 90 days.

How long should a JWT token expire? ›

Using an expired JWT will cause operations to fail. As you saw above, we are told how long a token is valid through expires_in . This value is normally 1200 seconds or 20 minutes.

How much data can be stored in JWT? ›

The size of a JWT is limited by the maximum size of an HTTP header, which is typically 8KB.

What is the difference between JWT and OAuth? ›

JWT is mainly used for APIs while OAuth can be used for web, browser, API, and various apps or resources. JWT token vs oauth token: JWT defines a token format while OAuth deals in defining authorization protocols. JWT is simple and easy to learn from the initial stage while OAuth is complex.

What is the most secure way to store tokens? ›

Session storage can be considered more secure than local storage because the browser will remove any tokens automatically when the window is closed, so no tokens are left at rest.

Can you decode a JWT without secret? ›

Please note that anyone can decode the information contained in a JWT without knowing the private keys. For this reason, you should never put secret information like passwords or cryptographic keys in a JWT.

What are the three parts of a JWT? ›

Anatomy of a JWT

Figure 1 shows that a JWT consists of three parts: a header, payload, and signature. The header typically consists of two parts: the type of the token, which is JWT, and the algorithm that is used, such as HMAC SHA256 or RSA SHA256. It is Base64Url encoded to form the first part of the JWT.

Should you use a JWT as an API key? ›

Both JWT authentication and API Key authentication are good options when building a secure API. Each has benefits and drawbacks. JWT authentication is standardized and there are libraries you can use to implement API key authentication quickly. However it is typically more complex for your API consumers.

Should JWT be stored in cookie or session storage? ›

Storing JWT (JSON Web Token) in a cookie is considered safer than storing it in session storage or local storage for several reasons: Cookies are less vulnerable to Cross-Site Scripting (XSS) attacks than session storage or local storage.

Is it good to store JWT in database? ›

To reiterate, whatever you do, don't store a JWT in local storage (or session storage). If any of the third-party scripts you include in your page is compromised, it can access all your users' tokens. To keep them secure, you should always store JWTs inside an httpOnly cookie.

How to store JWT locally? ›

Optimal Secure Solution: Save JWT Tokens in the browser's memory and store the refresh token in a cookie
  1. Step 1: Generate and issue tokens. ...
  2. Step 2: Save the JSON web token in the browser session. ...
  3. Step 3: Save the refresh token in a secure HttpOnly Cookie. ...
  4. Step 4: How to refresh the JSON web tokens.
May 9, 2023

Where to store an authentication token? ›

Applications can use dedicated APIs, such as the Web Storage API or IndexedDB, to store tokens. Applications can also simply keep the token in memory or put them in cookies.

Top Articles
Latest Posts
Article information

Author: Rubie Ullrich

Last Updated:

Views: 5746

Rating: 4.1 / 5 (52 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Rubie Ullrich

Birthday: 1998-02-02

Address: 743 Stoltenberg Center, Genovevaville, NJ 59925-3119

Phone: +2202978377583

Job: Administration Engineer

Hobby: Surfing, Sailing, Listening to music, Web surfing, Kitesurfing, Geocaching, Backpacking

Introduction: My name is Rubie Ullrich, I am a enthusiastic, perfect, tender, vivacious, talented, famous, delightful person who loves writing and wants to share my knowledge and understanding with you.