Session fixation & Session hijacking
Posted December 12, 2008on:
Security is a very important issue on any web application. This is why I am very pleased to introduce a security corner on my blog where I will discuss on different types of attacks. Things I will discuss here will not be vague and general overviews. If you are looking for an introduction to security than things like PHP manual could serve you better.
hmm… session fixation, session hijacking. sounds cool huh? well, we will know these right away :p before that I would like to tell something on SESSION.
What is Session?
HTTP is known as a stateless protocol. which means that the webserver does not care multiple requests come from the same user. In other words you can say that HTTP don’t remember anything when the execution is finished. Sessions are used to create a state in between requests even when they occur after weeks from each other.
Sessions are maintained by passing a unique session identiﬁer between requests typically in a cookie (which usually resides in webserver’s file system). Session can also be passed in forms and query arguments. PHP handles sessions transparently through a combination of cookies and URL rewriting, when session.use_trans_sid is turned on in php.ini (it is off by default in PHP5) by generating a unique session ID and using it track a local data store (by default, a ﬁle in the system’s temporary directory in my case /tmp/) where session data is saved at the end of every request.
Caution: session_start() must be called before any output is sent to the browser, because it will try to set a cookie by sending a response header.
Most of the other attacks like XSS, CSRF etc could be prevented by ﬁltering input and escaping output, but session attacks cannot. Rather it is necessary to plan for them and identify potential problem areas of your application. Two notorious forms of session attacks are session ﬁxation and session hijacking.
Whenever a visitor ﬁrst visit a page in your application that calls session_start(), then a session is created for the user. PHP generates a random session identiﬁer to identify the user (you can see this identifier by using session_id()) which is also known as session token, and then it sends a Set-Cookie header to the client. By default, the name of this cookie is PHPSESSID, but you can change the cookie name in php.ini or by using the session_name() function. On subsequent visits, the client identiﬁes the user with the cookie, and this is how the application maintains state.
It is possible to set the session identiﬁer manually through the query string, forcing the use of a particular session. This simple attack is called session ﬁxation because the attacker ﬁxes the session. This is most commonly achieved by creating a link to your application and appending the session identiﬁer that the attacker wishes to give any user clicking the link.
<a href="http://yoursite.com/index.php?PHPSESSID=123456">Fix the session</a>
By clicking the above link an would be attacker could get access the protected user’s login credentials and so on. If the user logs in while using the provided session identiﬁer, the attacker may be able to ride on the same session and gain access to the user’s account. This is why session ﬁxation is sometimes referred to as session riding.
Protecting Session Fixation:
Since the purpose of the attack is to gain a higher level of privilege, the points at which the attack should be blocked are clear: every time a user’s access level changes, it is necessary to regenerate the session identiﬁer. With PHP makes this can be easily done by using session_regenerate_id(). Don’t forget to use TRUE in parameter if you want to delete the previous session like this:
While this will protect users from having their session ﬁxed and offering easy access to any would-be attacker, it won’t help much against another common session attack known as session hijacking. This is a rather generic term used to describe any means by which an attacker gains a user’s valid session identiﬁer (rather than providing one of his own).
For example, suppose that a user logs in. If the session identiﬁer is regenerated, they have a new session ID. What if an attacker discovers this new ID and attempts to use it to gain access through that user’s session? It is then necessary to use other means to identify the user.
Protecting Session Hijacking:
One way to identify the user in addition to the session identiﬁer is to check various request headers sent by the client. One request header that is particularly helpful and does not change between requests is the User-Agent header. Since it is unlikely
(at least in most legitimate cases) that a user will change from one browser to another while using the same session, this header can be used to determine a possible session hijacking attempt.
After a successful login attempt, store the User-Agent into the session:
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
Then, on subsequent page loads, check to ensure that the User-Agent has not changed. If it has changed, then that is cause for concern, and the user should log in again.
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT'])
// Force user to log in again