JWT Issues - Using JWTs as Session Tokens

JWT Issues

Using JWTs as Session Tokens

Andrea Hauser
by Andrea Hauser
on October 14, 2021
time to read: 9 minutes

Keypoints

These are the security issues with JWT

  • JWTs are mistakenly used as a replacement for session tokens
  • This ignores the fact that JWTs cannot be revoked or invalidated
  • JWTs should only be used for applications that are completely stateless
  • When storing JWTs, care should be taken to avoid XSS or CSRF vulnerabilities

During recent tests, we have encountered a number of web applications that use JSON Web Tokens (JWT) in the same way as classic session tokens. It was discovered that not all developers are aware that the usage of JWTs causes problems with the revocation of such tokens and therefore also with the logout of users. This article will discuss these and other problems with JWTs and show in which situations the usage of JWTs makes sense.

Definition of JWT and Classic Session Token

RFC 7519 defines JWT as a means of representing claims that are transferred between two parties. Accordingly, when JWTs are used to manage sessions of users, a user’s authorisation is recorded in the JWT. Such a claim transported in a JWT could look like the following:

{"user":"test", "id":"123", "gui":"full_access", "admin":"true", "exp":"1634205600"}

This claim contains everything that is necessary for the validation of a user’s authorisations on the server side. Accordingly, the validity of the claim can be determined by validating the signature of the JWT. Which means there is no session per se, instead the validity of the claim is checked on the server side with every request. For example, the claim shown in the example above is valid until the 14th of October 2021 at 12:00:00. After that, the JWT will expire due to the exp parameter.

Sequence of checking permissions with JWTs

A classical session token, which is usually stored in the browser via cookies, only contains an ID with which the information about the user can be retrieved on the server side. A specific session of a user is linked to the session token. As a rule, a session is terminated after a certain period of inactivity or in the event of a logout and the session token can no longer be used.

Sequence of checking permissions with session tokens

Problematic Usage of JWTs as Session Tokens

In the article Signed JSON Web Token, some vulnerabilities such as the algorithm:none attack and the problems of certain signature algorithms that can be used were already discussed. These problems will not be discussed in detail here.

As can already be gathered from the definition of JWTs above, there is no way to invalidate or revoke JWTs once they have been issued. This also means that no logout can be implemented without custom developments. Furthermore, it is not possible to adjust the permissions contained in a claim while a JWT is still valid. If the claim

{"user":"test", "id":"123", "gui":"full_access", "admin":"true", "exp":"1634205600"}

is used as an example, this would mean that the user test has administrative rights until the JWT expires, even if these rights have already been withdrawn on the server side. Since the verification of permissions is only done through the JWT, the server-side adjustment of permissions cannot be detected. Developers need to be aware of these limitations before the usage of JWTs is implemented. As OWASP also recommends in their JWT Cheat Sheet, JWTs should only be used if the web application is completely stateless. Otherwise, classic systems with sessions should be considered.

Problematic of storing JWTs

In addition to the problem of invalidating JWTs, there is also the problem of storing JWTs. Normally, JWTs are sent via a header. Therefore, it must be possible to access the JWT with JavaScript in order to be able to create this header. However, this opens up the problem that the token must be stored either in the localStorage or in a cookie without httpOnly protection and can therefore be read in the event of an XSS vulnerability.

To solve this problem, two different approaches are presented by OWASP. On the one hand, the JWT can be stored in a hardened cookie and processed directly from the cookie. The hardened cookie must contain at least the following attributes:

Secure; HttpOnly;

In addition, it must be considered that with the usage of cookies, countermeasures against cross site request forgery attacks must now be implemented. For modern browsers, setting the attribute SameSite=Strict in the cookie should be sufficient. A detailed description of a CSRF attack as well as countermeasures are covered in our article Cross Site Request Forgery – Is CSRF dead?.

In principle, the claims from a JWT should not be needed on the client side. However, if information from the JWT is nevertheless needed to be accessed on the client side, the second solution approach of OWASP can be implemented. The details and implications of such an implementation are described in more detail in the sections Token storage on the client side and Token sidejacking in the OWASP JWT Cheat Sheet.

What are JWTs useful for?

As already mentioned, JWTs are particularly useful when an application is completely stateless. Otherwise, JWTs can be used as a token mechanism in OAuth 2.0 flows. Also a very good place to use JWTs are use cases where they can be used as a one-time authorisation token. As an example of such a use case, an application can be taken that allows users to download files, among other things. The server that provides the files is a separate, stateless server or service. In this case, the main application can issue a download token in JWT format, which can then be used by the user to download their file from the download server. In this case, the JWTs have the following properties:

Conclusion

JWTs are not fundamentally a bad thing. They simply have to be used in the situations they are intended for in order to be worthwhile. In a web application where logging out users or adjusting permissions has to happen immediately, JWTs are not the right solution without having to build further custom logic. JWTs should only be used in areas that are actually completely stateless. Otherwise, tried and tested classic session tokens should be used. If JWTs are used for a web application, care should be taken how they are stored so that the chosen storage method does not lead to problems with XSS or CSRF attacks.

About the Author

Andrea Hauser

Andrea Hauser graduated with a Bachelor of Science FHO in information technology at the University of Applied Sciences Rapperswil. She is focusing her offensive work on web application security testing and the realization of social engineering campaigns. Her research focus is creating and analyzing deepfakes. (ORCID 0000-0002-5161-8658)

Links

You want to bring your logging and monitoring to the next level?

Our experts will get in contact with you!

×
Ways of attacking Generative AI

Ways of attacking Generative AI

Andrea Hauser

XML Injection

XML Injection

Andrea Hauser

Burp Macros

Burp Macros

Andrea Hauser

WebSocket Fuzzing

WebSocket Fuzzing

Andrea Hauser

You want more?

Further articles available here

You need support in such a project?

Our experts will get in contact with you!

You want more?

Further articles available here