Web security - Sessions and cookies

Many web applications use a session to make a customizable environment process users activities. As the HTTP protocol has been defined as a stateless protocol, it is theoretically impossible for HTTP to "remember" actions or someone as each HTTP request is completely independent of another.

Web applications therefore use a session to maintain state between HTTP requests. Sessions basics is to manage a unique identifier for each user such that every user request can be tied by this identifier.

User identification is usually based on a series of random numbers and of letters (usually 32). This is very thin, and let easily identifiers to be "stolen"  in a mean to impersonate users.

The session identifier is passed in the query request via one of three processes:

  • Via URL, so-called trans-sid;
  • Via a form hidden field, that is also of trans sid, but for POST requests;
  • Via a cookie.

Based on this, we distinguish no fewer than three types of attacks in session that leads to idendity theft:

  • Interception;
  • Prediction;
  • Fixing.

Interception and prediction

Prediction is about to guess a valid session identifier. Native session mechanism management (for PHP, Java, .NET...) was designed to generate highly random identifiers. It is therefore very unlikely that valid session identifier can be guessed.

Remains handling of the sessions storage, and the case of shared accommodation, that will be discussed in another article here.

Iterception is as its name implies, about to intercept the used identifier. This technique is very easy in case of the identifier is propagated in the URL on HTTP GET request.

In the case of cookie based identification, and when the user does not accept cookies, application must be resigned to pass the session id via another process. It's called trans-sid.

In case of PHP application for example, there is an option in php.ini to handle that. If session.use_trans_sid is 1, then This allows PHP to pass the session id via GET, from page to page (except for forms POST where a hidden field is added in this case). The URL then looks something like this: http://mysite.com/mypage.php?PHPSESSID=d10v5fg8r7g42901v4g87r1ds4on54f3

I will not draw a picture to show how easy it is then to use this session identifier. In addition, most users who share URLs with friends tend to copy / paste the entire URL, giving their username, not knowing then that the person may click the link and use the session he gave.

Another danger comes from the HTTP referrer, because it also contains the login session. Leave a site A to site B, may give the site an opportunity to B to impersonate you on the site A.

But as we have also seen in the CSRF article, the browser will rewrite all the links by adding the sessid at the end. Thus, if on a forum for example, someone posts a false image, it will also recover your sessid.

All this only works if the user does not accept cookies or if it was not already using a cookie representing a used session.

Whatever the method are, an attacker can still listen to the network, and retrieve the ID of HTTP session in the frame. Because it is passed via GET, POST, or cookie, the session id goes from client to server, and none of the methods can prevent viewing the network and counter strike the Man In The Middle attack.

A good protection must enable an encryption system such as SSL, which encrypts HTTP frames.

Attachment

All this leads to a fluent method that is used: fixation. Attachment is the fact to determine a session ID before using the application (it is "fixed"). Here is a example:

  1. The attacker sends a URL to a user http://asite.com/login.php?PHPSESSID=1234;
  2. The user follows the link, if it does not have a session cookie, it will initialize the session 1234;
  3. The user enters his login and identify;
  4. The attacker then follows http://asite.com/index.php?PHPSESSID=1234 and is at the root of the site, with the newly authenticated user session;
  5. If the user is an administrator, the attacker can directly go to http://asite.com/admin.php?PHPSESSID=1234.

The example is simple but it is clear enough to see that the sessid is set before the server assigns the session. Under IIS, this is not possible because IIS will refuse an identifier that was not previously generated by server.

After that, visit to the pirate index.php, retrieves the identifier that the server sent (in the cookie for example), then send it to the victim, and wait for him to authenticate.

To protect application, avoid using the trans-sid (for this, the session.uses-trans-sid 0 in php.ini must be used). But that does not specify that PHP does not rewrite the output by adding the sessid. True security comes here, session.uses of-only-cookie = 1

Indeed this option will tell PHP to simply ignore any session identifiers, past other than cookie. The cookie has the advantage of being passed in the HTTP headers. It remains invisible, it may greatly reduces the risk of session theft, but this is still possible.

Even if the server only accepts cookies to transport the session id, there is several methods to do this:

  • Let us not forget that when setting session, only SSL encryption type is absolutely worthless, at any point of network where cookies are attacked. Allowing a third party to read or write its cookies constitutes vulnerability;
  • DNS attack type can have the same effect by sending the user to a script that goes in read / write its cookies.

Using a client side script

Most browsers accept scripts like Javascript or VBScript, where these two languages allows cookie initialization in the browser. A same origin policy rules can however prevent a cookie in a domain or one of its subdomains to run in other domain.

However, the attacker will try to force the browser of the victim to inject a cookie with a session identifier with a XSS attack, in a simple document.cookie = sessionid = 1234 initialization allowed by Javascript.

It can even specify a cookie for a domain root, and thus capable of operating on all subdomains document.cookie = sessionid = 1234; mydomaine.dom domain =.;

Injection of meta-tags

With a META tag html, you can specify a cookie like:

<meta%20http-equiv=Set-Cookie%20content="sessionid=1234;>

And unlike scripts, we can not stop reading a META. It will be analyzed and taken into account even outside of html HEAD tags.

Protections

To sum up: a hacker makes us connect with an identifier it chose. The solution here is to not accept session ID from the outside (as in IIS), and thus to regenerate the ID each time it will be useful.

session_regenerate_id () restores a session identifier to the session, without destroying it.

Thus, after each user authentication, or after each elevation of privilege within the web application it is necessary to change the session id to ensure that the session was not from questionable (fixed).

It is also very important during regeneration, to kill the old session. You have to go to TRUE session_regenerate_id (), the former session identifier owned by the hacker will be completely destroyed. This option is only available PHP5.1.

Another protection can be regenerating the session for each HTTP request: the final solution unfortunately it is often too resource-intensive in the scalability and is inappliquable quickly.

You should know that a session does not last forever, but at least it lasts, the more it is secure. Therefore play on two tables: time of validity of the session cookie, and time of validity of the session on the server.

By default, when PHP sends the session cookie, it specifies the timeout in the "browser session" this is to say when you close the browser, not the tab representing the page.

On server side, storing session in a database is simple, so just store the date and make a comparison.

When using files, a cron job will compare the date to the file to the current date, which can help therefore to specify a limit.

If you have access to cron, PHP uses a garbage collector that is very simple: if session.gc_probability = 1 and session.gc_divisor = 100, then all HTTP requests 1OO back over session.gc_maxlifetime second will be deleted. This will ensure that the frequency is  appropriate: not too often at the risk of load server and its file system, but not too often not allowed to continue at the risk of a data session too old, could be intercepted.

Even if it is hackable, the more you sow the path with obstacles, the more you make it difficult to pirate.

Do not interfere with users, they too often shed by identifying, for example.

You can also check the referrer side. If a page access authorization is accessed from outside the site, consider that the session is forged and destroy it immediately (a PHP directive "Session.referer_check" is made for that).

Same thing with the browser signature: It is still uncommon that a user moves from one page to another, by changing the browser ... So if a hacker is involved, it can be done with a different browser than the victim. So, make sure the sequence of pages in your session is done with the same browser.

If the transition from page A to page B indicates a change in browser, destroy the session and ask Authentication again. Because even if the user changes the browser, cookies themselves are dependent on browser. In moving from A to B, if the user changes the browser, the session cookie sent to B will not be the same that was sent to A.

Finally, remember to warn the user. Give it option that he can always disconnect. A disconnect, kill the local session and cookies thereto. It is easy to paste sessions in cybercafes ...

Please publish modules in offcanvas position.