Stop using JWT as the Session system! problematic and dangerous


JSON Web Tokens, also known as JWTs. This article will explain in detail: why JWT is not suitable for storing Session, and the security risks caused by JWT. I hope you have a deeper understanding of JWT!

Original address: http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions

Unfortunately, I find that more and more people are recommending the use of JWT to manage user sessions on websites (Session). In this article, I'll explain why this is a very, very premature idea.

To avoid confusion and ambiguity, some terms are first defined:

  • Stateless JWT (Stateless JWT): JWT Token containing Session data. Session data will be directly encoded into
    Token.
  • Stateful JWT (Stateful JWT): A JWT Token that contains a Session reference or its ID. Session
    data is stored on the server side.
  • Session token (also known as Session cookie): a standard session ID that can be signed, such as the
    session mechanism that has been used for a long time in various web frameworks (translator's note: including Laravel). Session data is also stored on the server side.

It needs to be clarified: This article does not provoke the debate of "never use JWT" - it just wants to show that JWT is not suitable as a Session mechanism and is very dangerous. JWT does have its place in other ways. At the end of this article, I will briefly describe some reasonable uses.

insert image description here

first need to explain

Many people mistakenly try to compare Cookies and JWT. This kind of comparison is meaningless, just like comparing memory and hard disk. Cookies are a storage mechanism, while JWT Tokens are encrypted and signed tokens.

They are not opposites - rather, they can be used independently or in combination. The correct comparison should be: Session vs. JWT, and Cookies vs. Local Storage.

In this article, I'll compare JWT Tokens to Sessions, and occasionally Cookies to Local Storage. Such a comparison makes sense.

The anecdotal advantages of JWT

When people Amway JWT, they often promote the following benefits:

  • Easy to scale horizontally
  • easy to use
  • more flexible
  • safer
  • Built-in expiration time function
  • No need to ask the user "this website uses cookies"
  • Prevents CSRF attacks
    More suitable for mobile terminals
    Suitable for users who block Cookies

I will explain why the above points are wrong or misleading one by one, and some of the explanations may be a bit vague, mainly because the expressions of these "benefits" are themselves relatively vague.

Easy to scale horizontally?

This is the only "benefit" on the list that is partially true on a technical level, but only if you are using stateless JWT Tokens. In reality, however, almost no one needs this kind of scale-out capability. There are many simpler ways to expand. Unless you are operating and maintaining a system as large as Taobao, you don't need stateless sessions at all.

Some examples of extending Stateful sessions:

1. "Running multiple backend processes on a single server": Just install the Redis service on this server to store the Session.
2. "Run multiple servers": Only one dedicated Redis server is needed to store Session.
3. "Running multiple servers in multiple clusters": session persistence (also known as: sticky session).
All the above scenarios are well supported in the existing software system, and the possibility of your application requiring special processing is basically zero.

Perhaps you are thinking that you should leave more room for adjustments in your application in case some special operation is required in the future. But practice tells us that it is not difficult to replace the Session mechanism in the future. The only cost is that all users will be forced to log out once after migration. We don't need to implement JWT up front, especially considering the negative impact it brings.

easy to use?

This is really not. You have to deal with the Session management mechanism yourself, whether it is a client or a server. While standard Session cookies work out of the box, JWT is no simpler.

To put it bluntly, at present, various out-of-the-box frameworks do not automatically integrate JWT, and developers need to handle it by themselves.

more flexible?

I haven't seen anyone successfully explain "how JWT is more flexible". Almost every mainstream Session implementation allows you to store data directly into the Session, which is no different from the JWT mechanism. As far as I know, it's just a buzzword.

safer?

A large number of people believe that JWT Tokens are "more secure" because of the use of encryption technology. In fact, signed cookies are also more secure than unsigned cookies, but this is by no means unique to JWT. Excellent Session implementations use signed cookies (Translator's Note: such as Laravel).

"Using cryptography" doesn't magically make something more secure, it has to serve a specific purpose and be a valid solution for that purpose. Using encryption incorrectly can actually reduce security.

Another argument for "more secure" that I have heard many times is "JWT does not use Cookies to transmit Tokens". This is ridiculous, a cookie is nothing more than an HTTP header, and there is nothing insecure about using cookies. In fact, cookies are particularly well protected against malicious client-side code.

If you are worried about someone intercepting your Session cookies, then you should consider using TLS. If TLS is not used, any type of session mechanism may be intercepted, including JWT.

Built-in expiration time function?

Meaningless and useless features. Expiration control can also be implemented on the server side, and many Session implementations do this. In fact, the expiration control on the server side is more reasonable, so that your application can clear the Session data that is no longer needed; if you use stateless JWT Tokens and rely on its expiration mechanism, you cannot do this.

This expiration time actually adds complexity in some scenarios.

No need to ask users "this website uses cookies"?

Totally wrong. There is no such thing as a "cookies law" - the various laws on cookies actually cover any type of "persistent ID that is not strictly necessary for the proper functioning of a service", any Session mechanism you can think of is included.

simply put:

  • If the Session or Token is used for system function purposes (for example: to maintain the user's login status), then no matter how the Session is stored, the user's consent is not required.
  • If the Session or Token is used for other purposes (for example: data analysis, tracking), then no matter how the Session is stored, the user needs to be asked for permission.

Preventing CSRF attacks?

This is really not. There are roughly two ways to store JWT Tokens:

"Store in Cookie": still vulnerable to CSRF attacks, or need special handling to protect it from attacks.
"Elsewhere, such as Local Storage": While not vulnerable to CSRF attacks, your site requires JavaScript to function properly; and this leads to a completely different, perhaps more serious vulnerability. I will elaborate on this later.
The only correct way to prevent CSRF attacks is to use CSRF Tokens. The Session mechanism has nothing to do with this.

More suitable for mobile terminals?

baseless. Almost all currently available browsers support Cookies and therefore Sessions. The same is true for mainstream mobile development frameworks as well as serious HTTP client libraries. This is not a problem at all.

For users who block cookies?

Not too possible. Users typically block persistent data in any sense, not just cookies. For example, Local Storage and any storage mechanism that can persist the Session (whether using JWT or not). It doesn't matter how simple you use JWTs, that's a whole other question. Also, trying to make the authentication process work without cookies is basically useless.

Most importantly, most users who disable all cookies understand that this will render authentication unusable, and they will individually unblock the sites they care about. This is not a problem that you, a web developer, should solve. A better solution is to explain in detail to your users why your website requires cookies to use.

Disadvantages of JWTs

Above, I've explained common misconceptions and why they're wrong. You might be thinking: "This doesn't seem like a big deal, even if JWT doesn't bring any benefits, it won't make a difference", then you are very wrong.

There are many disadvantages in using JWT as the Session mechanism, some of which will cause serious security problems.

more space

JWT Tokens are not actually "small". Especially when using stateless JWT, all data will be directly encoded into Tokens, which will soon exceed the length limit of Cookies or URL. You might be thinking of storing them in Local Storage, however...

more unsafe

If JWT Tokens are stored in Cookies, the security is the same as other Session mechanisms. But if you store JWT elsewhere, it will lead to a new vulnerability, see https://blog.prevoty.com/does-jwt-put-your-web-app-at-risk, especially "Storing sessions "this part.

❝Local Storage, a great feature in HTML5, enables browsers to support Key/Value storage. So should we store JWT Tokens in Local Storage? Considering that these Tokens may become larger and larger, it may be useful. Cookies are usually It is more advantageous when storing around 4k. For larger Tokens, Cookies may not be competent, and Local Storage may become a clear solution. However, Local Storage does not provide any security measures similar to Cookies. LocalStorage is different from Cookies , does not send stored data on every request. The only way to get data is by using JavaScript, which means that any JavaScript script injected by an attacker can access or leak data at will just by passing content security policy checks. Not only Well, JavaScript doesn't care or track whether data is sent over HTTPS or not. As far as JavaScript is concerned, it's just data, and the browser treats it like any other data. After all the troubles of generations of engineers, Finally being able to ensure that no one has malicious access to our cookies, yet we try to ignore these experiences. Seems like a step backwards to me. ❞ Simply put, "
Using cookies is not optional", whether you use them or not JWT.

cannot be destroyed alone

There are more security concerns. Unlike Sessions, which can be destroyed on the server side alone at any time. Stateless JWT Tokens cannot be destroyed individually. According to the design of JWT, Tokens will remain valid until they expire no matter what. For example, this means that when an attack is detected, you cannot destroy the attacker's session. Similarly, after the user changes the password, the old Sessions cannot be destroyed.

There is little we can do about it, unless we rebuild a complex and stateful (Stateful) infrastructure to explicitly detect or reject specific Sessions, otherwise we will not be able to end the session. But this completely defeats the original purpose of using stateless JWT tokens.

data delay

Similar to the security issue above, there is another potential security concern. Just like caching, data stored in stateless tokens will eventually become "stale" and no longer reflect the latest data in the database.

This means that expired information may be retained in Tokens, for example: the old URL modified by the user on the personal information page. More seriously, it may be a Token with admin privileges, even if you have revoked the admin privileges. Because these Tokens cannot be destroyed, there is no other way than shutting down the entire system in the face of administrator privileges that need to be removed.

The implementation library lacks production validation or does not exist at all

You may be thinking that all of the above questions revolve around "stateless JWT", which is mostly true. However, using stateful tokens is basically equivalent to traditional session cookies... but lacks the extensive validation of a production environment.

Existing Session implementations (such as express-session https://github.com/expressjs/sessio for Express) have been used in production environments for many, many years, and their security has been greatly improved. If you use JWT as a temporary replacement for Session cookies, you will not enjoy these benefits, and you will have to constantly improve your own implementation (it is easy to introduce bugs in the process), or use a third-party implementation, although not yet in the real world. There are a lot of applications.

❝In fact, Laravel Passport uses a method similar to "stateful JWT" to store OAuth Access Token. Fortunately, Passport already has many practical applications and does not rely entirely on JWT.

in conclusion

Stateless JWT Tokens cannot be destroyed or updated individually, depending on how you store them, it may also cause length problems and security risks. Stateful JWT Tokens are no different from Session cookies in terms of function, but they lack the verification of the production environment, the implementation of a large number of Reviews, and good client support.

Unless you work in a company of the size of BAT, there is no reason to use JWT as a Session mechanism. Or use Session directly.

So... what are JWTs good for?

At the beginning of this article, I mentioned that although JWT is not suitable as a Session mechanism, it does have its place in other aspects. While the claim still holds, an example of a particularly effective use of JWTs is usually as a one-time authorization token.

引用JSON Web Token specification(https://tools.ietf.org/html/rfc7519):

❝JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. […] enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.❞

In this context, a "Claim" could be a "command", a one-time authentication, or basically anything that can be described by the following sentence:

❝Hello Server B, Server A told me I can <…Claim…>, here is my proof: <…Key…>.❞

For example, you have a file service, users must be authenticated to download files, but the files themselves are stored in a completely separate and stateless "download server". In this case, you may want the "Application Server (Server A)" to issue one-time "Download Tokens", which users can use to go to the "Download Server (Server B)" to obtain the required files.

Using JWT in this way has several clear properties:

  • Tokens have a short lifespan. They only need to be available within a few minutes for the client to start the download.
  • Tokens are single use only. The application server should issue a new token on each download. So any Token that is only used for one request will be discarded, and there is no persistent state.
  • Application servers still use Sessions. The download-only server uses Tokens to authorize each download since it doesn't require any persistent state.

As you can see above, combining Sessions and JWT Tokens makes sense. They each have their own purpose, and sometimes you need to use both together. Just don't use JWTs for "persistent, long-term" data.

Guess you like

Origin blog.csdn.net/weixin_44834205/article/details/128069705