Learn what session fixation attacks are and how to protect your web application from them. You can read the original article here.
HTTP is a stateless protocol. As such, web applications must give users something that they can use to identify themselves with as they browse the website (and send more HTTP requests). This something is called a session identifier and usually is stored in a cookie.
On the HTTP level, it could look like this.
User types "www.example.com" in the URL bar and hits enter. The browser sends an HTTP GET request to the front page.
GET / HTTP/1.1 Host: www.example.com
To identify the user in subsequent requests, the website returns a session cookie to the user in the first HTTP response.
HTTP/1.1 200 OK Set-Cookie: SessionId=123
The browser will include the cookie in subsequent requests to the site, allowing the website to identify the user.
GET / HTTP/1.1 Host: www.example.com Cookie: SessionId=123
Session fixation happens when an attacker manages to set the target user's session identifier into a value that is known to the attacker. For example, the attacker might first get a legitimate session identifier from the webserver like so:
GET / HTTP/1.1 Host: www.example.com
HTTP/1.1 200 OK Set-Cookie: SessionId=ABC123
Then the attacker forces this cookie into the target user's browser, causing a situation where both the attacker and the target have the same session cookie in their browsers.
At this point, the cookie is harmless because no-one has yet logged in with it. But what if the user logs in, and the web application authenticates the user's session cookie, elevating it into an authenticated state?
The user is now logged in, but so is the attacker, who is also in possession of the session identifier.
It depends on the application, but here are the usual ways to force a session identifier into someone's browser.
In a man-in-the-middle attack the attacker has control over the target user's network traffic and can forge a
Set-Cookie reply or a
document.cookie call on the page which sets the user's session id.
All subdomains can overwrite an application's cookies by default, so if there is, e.g., an XSS vulnerability on foo.example.com, an attacker can use it to change the user's cookie on www.example.com.
Someone with physical access to the web-browser can easily set cookies for a website before the next computer user logs in.
Some older application frameworks do silly things like taking session identifiers directly from URL parameters, making the application vulnerable to session fixation attacks.
In such scenarios, the attacker can create a link with the attacker's session ID and get someone to open it.
If you see something like "?JSESSIONID=12345" in your URL, then you might want to do something about it.
As with all attacks, there are measures that developers can take to prevent session fixation.
Creating a new session identifier upon login is the most critical defense against session fixation attacks.
Instead of authenticating the user's existing (pre-authenticated) session identifier, the application should grant the user a new, authenticated session identifier.
Now the attacker cannot hijack Jim's session anymore.
Most modern application frameworks follow this behavior, but there are exceptions. Make sure your application returns an entirely new session identifier on login.
POST /auth/login HTTP/1.1 Cookie: SessionId=ABC123 ... user=Jim&password=Cat
HTTP/1.1 301 Moved Location: /profile Set-Cookie: 'SessionId=xY729x...'
One of the threats is a man-in-the-middle (MITM) attack. An attacker intercepts the connections between the user and your web server and injects a
Set-Cookie header with the attacker's cookie.
Even if we do create a new session ID upon authentication, there are other session fixation attacks that we still want to prevent, such as the attacker logging in the target user with the attacker's user account.
To prevent MITM attacks against your web application, use HTTPS, preloaded HSTS, and configure your TLS settings properly.
The application should protect its cookies with the
__Host prefix and the
Secure attribute to prevent a compromised subdomain or a network attacker from overwriting the user's cookies.
The application can do nothing to prevent the cookie from being overwritten in the event of a successful XSS (Cross-Site Scripting) attack.
As such (and for many other reasons), we have to carefully avoid XSS vulnerabilities and use a strict CSP (Content Security Policy) to further harden our application against them.
As mentioned above, legacy application frameworks can have features that make them vulnerable to session fixation attacks by design. For example, J2EE applications support session management through URL rewriting.
The best defense is to stay away from legacy frameworks and develop with modern tools. However, if you're stuck with old technology, then at least find the configuration setting or create a filter to disable the dangerous functionality.
Session fixation attacks happen when an attacker forces, or "fixates", a session identifier, a value known to the attacker, to a user's browser.
The primary threat is that the user logs in with the attacker's known session identifier, but there are other attacks such as the attacker logging in the user with the attacker's user account.
To protect your web application from session fixation attacks, we came up with the following defenses:
- Always create a new session ID upon authentication.
- Prevent MITM attacks with HTTPS, HSTS, and proper TLS security settings.
- Prevent cookie overwrites by protecting the cookie with __Host-prefix and Secure attribute.
- Avoid XSS vulnerabilities and prevent exploitation by using a strict CSP (Content Security Policy).
- Use modern application frameworks, or configure legacy frameworks carefully.
☝️ Subscribe to AppSec Monkey's email list, get our best content delivered straight to your inbox, and get our 2021 Web Application Security Checklist Spreadsheet for FREE as a welcome gift!
If you like this article, check out the other application security guides we have on AppSec Monkey as well.
Thanks for reading.