Session fixation is an issue whereby an attacker is able to set a session token for a victim, and therefore being able to hijack the victim’s session. HTTP pollution of a fixated cookie could potentially have devastating consequences.
A general recommendation and one (of many) ways to protect applications against this type of attacks is to delete the cookie before login to the application and issue a new cookie with a random session token upon successful authentication. However, it often introduces a new issue as cookies with different flags are normally treated as different ones..
First lets have a look at an important part of the RFC for HTTP State Management Mechanism (Cookies):
“Although cookies are serialized linearly in the Cookie header, servers SHOULD NOT rely upon the serialization order. In particular, if the Cookie header contains two cookies with the same name (e.g., that were set with different Path or Domain attributes), servers SHOULD NOT rely upon the order in which these cookies appear in the header. ” (http://tools.ietf.org/html/rfc6265)
Understandably this is part of the as-designed functionality of cookies.
Well, probably it is still not clear where is the vulnerability.
Let’s explain further:
One would assume that, if a cookie is set with the same name with another cookie, the one set now would overwrite the latter.
The same for deletion, update etc. However, this relies on the browser’s cookie handling as per the above quote and not on the server.
In general the server/application should never assume anything that it is not directly controlled by it.
The problem is that cookies with different flags are considered different, although they might have the same name. This will make most, (if not all) browsers to store them and send them BOTH at every request.
Although which one is send before or after depends on the browser, the weather, the tides and the planetary movements. Therefore, the value received by the application is unpredictable.
So, where is the vulnerability you ask?
If you can’t see it yet you might want to have a look in HTTP parameter pollution.
Two variables with the same name are sent to the server, which one is the one that the server will get? Also what happens if one of them gets validated by the application and then, using a different mechanism (parser etc.) the other one is the one that queries the database?
Let’s consider this scenario:
- The server deletes the (old) session cookie when the user tries to login to the application
- Then issues a new cookie after successful login.
- Additionally in many cases the server only accepts cookies issued by it.
- An attacker now logins to the application and gets a legitimate cookie bound to his session.
- Then he fixes this cookie in the victims browser. (He also makes sure to change the cookie flags)
- Now the victim tries to login to the application.
The attackers (fixed) cookie is sent to the server and the server responds back with a “expire cookie” to delete the old cookie. If this response does not have the same name AND the same flags as the fixed cookie, the browser might not actually delete it
The victim successfully authenticates to the application and a new session cookie is sent
Obviously all of the above will not lead to a session fixation - This heavily depends on how the application binds the session to the cookie and mostly on what it expects!
However, this kind of issue is not uncommon. In this case, the browser in every request will send both cookies. Which one would be read by the application is not certain and therefore this can lead to the application binding the attackers cookie to the victims session.
Then the attacker can use the session cookie to impersonate the victim to the application.
Going back to the RFC “servers SHOULD NOT rely upon the order in which these cookies appear in the header” add to that the general security term “Trust nothing” and you have a solution to the problem.
Addressing the issue:
Each application behaves differently and there is no easy way to make exact suggestions. Generic ones, on the other hand, led us here on the first place.
When a user authenticates and a new session is created, it is wise to destroy the previous session. Additionally, when designing and developing software, do not assume anything out of the applications control actually gets done.
Have no expectations! Do not expect that the received data will have the correct format/structure/form/etc.
Know your environment! Know how the application AND the server handle multiple parameters with the same name.
Be consistent in the way parameters are accesses and verified. Use the exact same mechanism to fetch parameters every time.
Validate all input to ensure it is in the expected and correct format.