The introduction

Recently, it has been found that many Web applications use JWT for session management, the reason is to avoid server-side storage sessions, or the pursuit of autonomous control, I do not know the use of JWT for session management has a huge security risk!

HTTP Session Management

Let’s start with the HTTP protocol. As we all know, HTTP is characterized by Q&A (one request, one response). Then based on the HTTP protocol, do a shopping website, to achieve user login, add goods to the shopping cart, the final purchase function. To do this, the easiest way to identify a series of actions by the same user is for the browser to send an account and password for each action, so that the server knows which user added the item to the cart and finally paid the bill. This may seem crude, and carrying an account and password on every request increases the risk of a breach.

To reduce the number of times the account password is carried in the request, we introduce a session-id thing. When you log into the shopping site with your account password (the first time you request it), the server returns a session-id after verification. After that, whether you add an item to your cart or place a final order, carry the session-id with you for each subsequent request. Why does carrying session-id tell you which client is doing this? Because the server associates the client’s account information with the session-ID that the session sends to the client, the session-ID and account associated information is session-data.

In the example above, session-data is stored on the server side. In fact, session-data can also be stored on the client. According to the location of session-data storage, there are two modes: Server Side session and Client Side session.

Server Side Session

The Server Side Session pattern is the most common, as in the previous shopping site example. In this mode, the client (the browser) stores the session-id in the local cookies. Its typical implementation is shown in the figure below:



In the figure above, User A is an old User who has already established A session. His Cookies store the Session_id with the value “AA01” and carry the Session_id in the request. After receiving the data, the server queries the corresponding data in the Session Database through SESSION_ID and uses it in the program. The server generates a New Session_id and returns it to the User, using the 401 status code, and tells the User to redirect to the login page to log in. If the New User is successfully logged in, the server will store his/her identity in the Session Table and associate it with the session_id generated at the beginning of the Session, so that subsequent requests will be similar to User A.

Client Side Session

The Client Side Session mode may seem a little strange to you, but it’s used a lot. Most Web systems that use JWT for Session management, for example, are in the Client Side Session mode. The so-called Client Side Session mode is to store the user’s session-data in the Client, so that the server is very busy. Its interaction process is roughly shown as follows:



In the figure above, User A on the left is an old User who has already established A session. His Cookies store SESSION_DATA, the value of which is the basic information of the current User. SESSION_DATA data is carried in the request. We know which user made the request. The New User on the right is logging in to establish a session. After successful verification, the server will generate SESSION_DATA information and return it to the client. Since the SESSION_DATA data is stored on the client side, the server will sign and even encrypt the generated SESSION_DATA data to prevent tampering.

Server Side VS Client Side

In the previous section, we discussed the principles of the Server Side Session and Client Side Session modes. Which one is better? Before comparing, set a baseline that limits functionality and security, rather than comparing the original implementation of the two patterns.

Server Side Session

Advantages:

  1. Session data is stored in the server side, which does not expose relevant information and has high security.
  2. Each request only needs to pass session-id, reducing traffic overhead;
  3. The server can easily revoke the session, control the number of concurrent sessions with the account and other comprehensive session policy management;

Disadvantages:

  1. When the server side is deployed in a distributed way, it needs to handle session-data sharing.

    Client Side Session

    Advantages:

  2. Decentralized storage;

Disadvantages:

  1. Session data is stored on the client side and carried on each request, increasing the risk of leakage.
  2. Each request needs to transfer more data, increasing traffic overhead;
  3. It is not convenient for the server to revoke the session and realize various session policy management.

As can be seen from the above comparison, the two modes have opposite features in terms of functionality and security. The Server Side Session pattern has many advantages, but why does the Client Side Session pattern still exist? The existence of the Client Side Session pattern is justified because the original implementation is simple! The server does not need to centrally store session-data data, and it does not need to process session-data lookup. Moreover, the server does not need to consider the distributed session-data sharing because it stores session-data in the Client Side. However, the simplicity of the original implementation of the Client Side Session pattern is not important to the user, because the user only uses existing libraries and frameworks, as long as they have good support. Therefore, the Server Side Session pattern is more common than the Client Side Session pattern.

What is JWT?

First of all, the JWT (JWE, JWS) standard only designs a tamper-proof token and is not designed for session management.



JSON Web Token(JWT) is an open data standard based on RFC 7519 that defines a loose and compact way of combining data using JSON objects to transfer information between applications (JWE for information encryption, JWS for signature). The JSON object can be digitally signed and verified. In general, JWT can sign data using the HMAC algorithm, the public/private key of RSA or ECDSA. A JWT usually consists of a HEADER, PAYLOAD, and SIGNATURE, using a “.” Links in the format shown above.

The defect of JWT

The JWT standard design looks good, but it’s actually a disaster because it’s designed to hide a number of security issues. Details are as follows:

Reset null encryption algorithm defects

JWT supports setting algorithms to “None”, and any Token is valid if you use the JWT library without setting it to turn off. To do this, set the ALG field in the first part of the JWT header to None, and then set the Signature field in the third part to NULL (i.e., do not add the Signature field). This token passes the verification successfully.

Key obfuscation attack

The two most commonly used algorithms for JWT are HMAC and RSA. HMAC (Symmetric Encryption Algorithm) uses the same key to sign and authenticate the tokens. While RSA (asymmetric encryption algorithm) requires two keys, the private key is used to generate JWT, and then its corresponding public key is used to decrypt and verify. If the public key is leaked (many people feel that the public key can be distributed), then the algorithm RS256 is modified to HS256, that is, asymmetric encryption is downgraded to symmetric encryption. The leaked public key is then used to sign the token. After the back-end receives the token, it will use the public key to verify the token according to the algorithm specified in the header, and then authentication is passed.

Key brute force cracking

If JWT uses a symmetric encryption algorithm, such as HS256, this means that the key that signed the token is also used to validate it. Since signature verification is a self-contained process, the valid key of the token itself can be tested without having to send it back to the application for verification. If the key setting is too simple, such as common words, birthday year, etc., combined with a known list of leaked passwords, the key will be quickly deciphered so that any token can be forged.

Kid specified attack

The kid is the key ID that exists in the JWT header and is an optional field that specifies the key of the encryption algorithm. If a new KID field is injected into the header and the key of HS256 algorithm is specified as 123456 to generate a new token, the server will use the specified key 123456 to verify the token after receiving the token.

How can I avoid JWT’s pitfalls

All of the problems listed above, except for key brute force cracking, are caused by the design of the JWT standard. If you choose to use the JWT standard, find a reliable implementation library and do security testing. Avoid symmetric encryption algorithms and properly configure security measures such as enabling validation JWT headers, disallowing ALG to be set to None, disallowing key degradation, and so on. But the best way to avoid it is to skip JWT and use Paseto, a new standard that replaces JWT.

The “benefits” of session management in JWT

First, as mentioned earlier, the JWT standard is not designed for session management, and certainly neither is the PASETO standard (the JWT standard’s replacement). Most Session management using JWT today is actually in the Client Side Session mode. As mentioned above, the Client Side Session mode stores Session data to the Client, so in order to prevent data tampering or leakage, the data stored on the Client is generally signed or encrypted. Many people use the JWT implementation library to place the session data in the PAYLOAD area, then generate a token and send it to the client. If the client is a web browser, it will even place the token received in localStorage through JS. This makes the developer feel like he’s in control, but it’s a lot of bugs all at once.

Those who use JWT for session management claim the following advantages:

  1. Natural support for distributed validation;
  2. Reduced server stress under high concurrency;
  3. Flexible and easy to use;
  4. More secure to prevent CSRF;
  5. It works better on mobile devices;
  6. For users who block cookies.

The aforementioned benefits are actually the result of the Client Side Session pattern and the autonomous control token. But I want to tell you that for the user, all of these advantages are false.

Natural support for distributed validation

This trait is true, but the reality is that few people actually need it. Because session sharing technology is very mature, existing software frameworks provide good support schemes.

Reduced server stress under high concurrency

It seems that with high concurrency, the Client Side Session mode has no server-side storage or query, which can reduce the stress on the server. However, if it is really high concurrency, you should think more about the stress that business processing puts on the server, rather than session storage and queries, because it is a drop in the bucket.

Flexible and easy to use

This is a complete mistake. Customization uses JWT for session management, which requires more code configuration to handle.

More secure against CSRF

The previous introduction to the JWT standard has shown that there are many design issues with JWT, not to mention the risk of information leakage from the Client Side Session mode. CSRF can be prevented unless you put the token in an area other than cookies, such as localStorage, and use JS to operate. However, this will bring greater risk.

It works better on mobile devices

A long time ago, some mobile browsers didn’t support cookies, but that’s a thing of the past. Mobile development frameworks now support cookies for every decent HTTP library, so this is not an issue at all.

For users who block cookies

Some users do block the use of cookies in order to avoid being tracked. But setting up a session requires login to verify your identity, so the user who has chosen to block cookies knows why I can’t log in. For users who really want to avoid tracking, not only cookies are blocked, but all client-side storage is blocked. Thus, in Client Side Session mode, there is no place to store the Session information.

If you prefer the Client Side Session pattern, and you really feel that the Client Side Session pattern meets your needs, you can simply use the implementation of the Client Side Session pattern supported by the server-side framework, rather than using JWT.

The right approach to HTTP session management

For secure sessions, HTTPS is the first thing you need to use to secure the transport channel. Then an implementation of the Server Side Session pattern, such as a cookie in a Web browser, is used to store a random identifier, session-id, which is paired with session-data stored on the Server. If you need to hold a longer session, add a long-term Remember Me ID instead of extending the session-id arbitrarily.

Some friends say that JWT Session management can be extended to avoid the shortcomings of Client Side Session mode. If the session is revoked, the server can join the blacklist mechanism, or the server can record the token issued, set the expiration date, and then compare each request. So the question is, is this still Client Side Session mode?

supplement

Some friends say that JWT implements single sign-on very easily. When asked, I have no answer. It refers to the realization of seamless authentication between systems through token authentication with the same key configuration of multiple systems. Yes, this is actually the advantage of the Client Side Session model, which allows for “single sign-on” in certain scenarios. This is not possible in most real-world scenarios, because you first need software systems developed by different companies that use JWT for session management, and then trust each other to share the same key (which is extremely insecure). Now the mainstream solution to single sign-on protocol is OIDC or OAuth2, again older is also SAML or CAS.

A friend asked, since JWT wasn’t designed for session management, what should it do? JWT works for one-time tokens, that is, short validity, one-time use. Such as a short-lived, one-time link for password retrieval emails, or a file download.

reference

[1] [EB/OL].http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/.2021-05-04 [2] paseto [EB/OL].https://github.com/paragonie/paseto/.2021-05-04 [3] [EB/OL].https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid.2021-05-04 [4] [EB/OL].https://geekkeen.github.io/http-cookie-session.html.2021-05-04 [5] [EB/OL].https://blog.by24.cn/archives/about-session.html.2021-05-04