You log into your Netflix account once; Then, you watch your favorite TV shows and movies without Netflix asking for your password again. This is a feature that we take for granted in the world of personalized user experiences. The reason websites don’t ask for our password with each action is a thing called web sessions. But, if you don’t secure web sessions on your website, the consequences for your users can be catastrophic. If you get this wrong, attackers could impersonate other users on your website.
What is a web session?
Web sessions help applications remember who the user is over the duration of his visit. This mechanism works in a similar way to a clothing store’s loyalty program.
The first time you buy something, the store creates a new customer file on you. They give you a loyalty card that is linked to your customer file.
The next time you visit the store, they ask you for your loyalty card. They use your card to access your customer file. The salesperson can now see what you purchased last time, and make personalized style recommendations.
In this analogy, the clothing store is the website, the loyalty card is the session cookie, and the customer file is the user’s state.
Let’s take a concrete example and see how the process works:
First visit and session creation
When you first visit a website, the web application will:
- Reserve a defined space where it will store your state. Depending on the configuration, this can take the form of some space in the RAM, a file on the filesystem, an entry in the database, or other data storing mechanisms.
- Give a reference to that allocated space. This reference is called the “session ID”. The application uses It to find the allocated space of a certain user.
- Send this “session ID” back to the user in the form of a cookie.
The following animation better illustrates the process:

Cookies are automatically sent with every request to the server. So, the next time you visit a page on that website, your browser sends the “session ID” cookie along. The application will use the session ID to access your state.
This process happens in the background. Your programming language, framework, and web server handle the connection between session ID and user state. In most cases, they provide you with a high level function to access that user state.
In Java, to initiate a user’s session, you need to call the instruction session = request.getSession();
.
Request here is an object of type HttpServletRequest. You can then use the object session as a data storage. You can store attributes via the call session.setAttribute('username', 'john.doe');
Login and populating the session
When you perform a login request, you send the application a username, password, and the session cookie that you received after your first visit to the website. The application uses the session cookie to access your state.
The application will then check if your login information is correct. Once confirmed, the application will change your session state. It will note that you logged in, and that you’re the user called “admin”. It might save other details in your state storage, depending on the application’s needs.
The following animation illustrates the process:

Accessing the session
When you make a request to access a resource on the platform, your browser sends the session cookie along. The application retrieves the session ID from the cookie, and uses it to look up the user’s session state. It can then perform checks if needed (Is the user logged in? Does the user have the required privileges to access this resource? …).
How to secure web sessions?
If you send the session ID of an authenticated user, the server will treat you as an authenticated user. Session IDs are like your bank account number that you give your banker so he can access your customer data.
In a website with many visitors, if you “guess” the session ID of another user, you can send it to the server and impersonate the victim. You can thus take control over his account.
So, it is important to make sure no attacker can access another user’s session ID. The following sections show how to secure web sessions.
Session ID entropy
The session ID takes the form of a string of random characters. An attacker could try all possible combinations of characters. His goal is to find a session ID that references a valid user. We call this a bruetforce attack.
Guessing the session ID of a user would lead to an account’s compromise; Thus, we should do everything to prevent that. To make a session ID difficult to guess, it needs to be long and randomly generated. Current security standards recommend at least a length of 128 bits (16 bytes).
With such a long session ID, it is impossible for attackers to launch bruteforce attacks. The attacker has to perform an HTTP request with each attempt; Thus, going through all possible combinations, with all the network delays, could take him hundreds of years.
The good news is that—for most programming languages and frameworks—the default settings are usually secure. All you need to do as a developer is not change the session ID generation algorithm.
Session cookie security
The session cookie is the cookie that stores the user’s session ID. We need to prevent malicious users from accessing that cookie.
Secure flag
When this flag is set to true, the browser will only send the session cookie if the communication channel is encrypted (HTTPS instead of HTTP).
HTTP traffic is not encrypted. Thus, attackers can intercept and inspect HTTP requests that the user’s browser sends. So, attackers can retrieve the session ID, and impersonate the user.
You should set up HTTPS on your website, and set this flag to TRUE on the session cookie.
For Java applications, edit the file web.xml to add the secure attribute as follows:
<web-app> <session-config> <cookie-config> <secure>true</secure> </cookie-config> </session-config> </web-app>
HttpOnly flag
When this flag is set to true, the browser won’t allow Javascript code to access the session cookie value. This protects session IDs, even if your application is at risk of Cross Site Scripting.
Cross Site Scripting (XSS) is a vulnerability where attackers can inject malicious Javascript code in your application. When people visit your website, their browsers will run the malicious code. The HttpOnly flag stops harmful Javascript from reaching your session cookie. This further protects your users’ session ID.
You should always set this flag to TRUE. For Java applications, edit the file web.xml to add the http-only attribute as follows:
<web-app> <session-config> <cookie-config> <http-only>true</http-only> <secure>true</secure> </cookie-config> </session-config> </web-app>
Session cookie name
The session cookie, by default, has a very descriptive name. For example, PHPSESSID (PHP), JSESSIONID (J2EE), ASP.NET_SessionId (ASP .NET), connect.sid (nodeJS)…
This discloses the technology you use on your website to the attacker. Now, he can focus all his research on vulnerabilities affecting your particular technology. It is best to hide all possible references to the technologies you use; Leave attackers with the least possible amount of information.
If your session cookie leaks such information, make sure to rename it to give it a generic name.
For Java applications, edit the file web.xml to add the name attribute as follows:
<web-app> <session-config> <cookie-config> <http-only>true</http-only> <name>SESSION</name> <secure>true</secure> </cookie-config> </session-config> </web-app>
Session fixation
The vulnerability
Session fixation is a complex vulnerability that requires physical access to a victim’s computer. Let’s explore this step by step.
Suppose an attacker has physical access to a victim’s computer, and the victim is not logged into your website. To start, the attacker uses the victim’s browser to visit your website. We will use the previous animation to illustrate :


The attacker then finds the session ID using the developer tools, writes it down, and leaves. In our example, he writes down the value bc71a.
Later, when the victim gets back to his computer, he will visit your website. The server already has a session for the user (having the id bc71a). When the victim logs in, the session ID bc71a will get populated with his information. He then uses the website like nothing happened:



Now, the attacker can perform the last step of the attack. Do you remember how he has access to that old session ID? He will create a new cookie in his own browser with the session ID value (bc71a). This allows him to impersonate the victim and take over their account.
Granted, this vulnerability is not easy to exploit. It requires physical access to a victim’s computer. But, when it comes to security, it’s better to be safe than sorry. Especially when the fix is easy to put in place, like in this case.
The fix
Here, the fix is very simple. You need to generate a new session when the user performs a login request.
Going by the previous example, don’t use the user’s session ID (bc71a). Instead, generate a new one for them (like 7d2f3). Thus, the application will store the user’s state under the reference 7d2f3. This new session ID has no association with the old session ID (bc71a). The attacker can’t do anything with that old session ID.


In Java, you simply need to call the function request.changeSessionId();
at the beginning of the login controller. This will generate a new session and send the new session cookie to the user
Logout
When the user clicks on the logout button, the server must invalidate his session. A mistake some developers make, is to only delete the session cookie. They do this by replying with the HTTP Header Set-Cookie: session_id=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
This would delete the session cookie from the user’s browser. But, the user’s session information is still stored on the server. If an attacker manages to somehow steal a user’s session ID, he will be able to use that session ID even after the user logs out of the application.
The proper way to invalidate a user’s session is by clearing his session on the server side, in addition to deleting the session cookie. Here’s how you can achieve that:
request.getSession().invalidate()
Convenience AND security
Web sessions are a feature that makes using a web applications convenient. You log in once, and enjoy the application until the session expires. In this instance, convenience doesn’t introduce big security risks. Secure web sessions on your application, and users will be both secure and satisfied with their experience.
Leave a Reply