Skip content

How JWT hijacking can be prevented

Json Web Tokens (JWTs) are commonly used in many applications to validate the client’s identity. The JWT token is provided during authentication in case of success and this is then used in all authenticated interactions to the application.

The validation of user’s identity is based on the user’s information stored in the JWT token which is signed by the server using JSON Web Signatures. The information exchanged within the JWT can also be encrypted using JSON Web Encryption however this is not widely used.

Although the JWT token can be used in web applications there is a number of caveats that come with the choice of implementing JWT authentication tokens that can result in them being hijacked.

In this article we will be discussing these security implementation issues and will uncover ways of preventing an attacker from hijacking JWT tokens.

JSON Web Token (JWT) – What are they all about?

Briefly, JWT is an authentication mechanism that can be used to identify the client and their permissions. The information exchanged in the JWT can be trusted since it uses JSON Web Signatures to sign the content preventing the data from being tampered with client-side.

The big advantage of using the JWTs is that they are stateless since all information needed is in the authentication JWT token, so no server-side session needs to be implemented. The information sent in the JWT can be validated by the server using the secret key used when the JWT token was created. This is much faster than querying the database or cache on the backend.

Implementing JSON Web Tokens

There are many ways of implementing JWTs however it is very common to use the following approach:

    • Client authenticates into the application;
    • If successful, the server creates the JWT, signs it with a secret key and sends the JWT in the response body;
    • The JWT is then stored client-side and in subsequent interactions with the server, the JWT is included in a HTTP header;
    • The server validates the JWT with the secret key, the identity and permissions of the user and sends back the response to the client whether or not it can access the resource.

The concerning bit in this process is where the JWT is being stored in the client-side because storing it insecurely would provide an attacker the possibility of hijacking it. Since the JWT is a session token can be used to access the resources that the compromised token has access to.

JWT storage

The JWT token needs to be stored in the client side in order to be used in the subsequent requests after authentication. The most common methods of storing the JWT are through HTML5 Web Storage or Cookies.

There are two ways of storing the JWT via HTML5 Web Storage as follows:

    • Local storage
    • Session storage

They are very similar in a way that both provide a key/value storage location within the browser for an application to query. The difference between both methods is that in local storage the JWT token becomes available across tabs in the same browser and therefore can be shared between tabs. The session storage prevents tabs in the same browser accessing the JWT and it is destroyed when closing the tab.

Another method of storing the JWT token is via Cookies, the JWT is sent and set with each HTTP request and response.

The implementation of these approaches is simple since both receive a JWT token from the server and this is stored in the browser. They are stateless since all information needed is in the JWT. Passing JWT token to the server is also simple since it can be sent via HTTP Authorisation Header or Cookie.

How about security?

Web storage is accessible via JavaScript which means that all JavaScript running in the application will have access to the JWT token. The security concern here is the possibility of the application being vulnerable to Cross-Site Scripting (XSS) vulnerability. This vulnerability allows an attacker to inject JavaScript into the vulnerable input and this could be leveraged to hijack the authentication JWT token.

Although there are ways of protecting the applications from being vulnerable to XSS by escaping and encoding all input, it is very common that the applications use JavaScript files from external sources which can be compromised. Resulting in malicious JavaScript payloads being included in the compromised JavaScript file. Consequently, the JWT token could be hijacked without being noticed.

Additionally, with local storage, the JWT token is not destroyed after closing the browser which can be compromised by an attacker if the users’ computer is compromised.

On the other hand, cookies are known to be a candidate to remediate this security issue because they have a security flag called ‘HttpOnly’ which prevents cookies from being accessed through JavaScript. Therefore, even if the application is vulnerable to XSS, an attacker would not be able to take advantage of this to hijack the JWT because this token is stored on the cookie and consequently protected from being accessed by JavaScript.

There is also the ‘Secure’ flag that can be configured in the cookie, preventing it from being sent over unencrypted communications.

Taking action

JWTs are authentication tokens that are simple to use and stateless, making them commonly used in many applications and APIs.

There are several approaches that can be used to store the authentication JWT token on the client-side however there are also security risks associated with its storage that can be leveraged by threat actors to hijack JWTs.

Cookies are the best approach to store the JWT token considering the additional security that it provides which can be used to prevent JWT to be hijacked. For more information on JWT authentication tokens, don’t hesitate to contact our LRQA team.