Proper Session Hijacking Prevention in PHP

Proper session hijacking prevention in PHP

Your configuration is awesome. You definitely read up on how to lock down php sessions. However this line of code negates a lot of the protection provided by your php configuration:
session_id(sha1(uniqid(microtime()));

This is a particularly awful method of generating a session id. Based on your configurations you are generating the session id from /dev/urandom which is a awesome entropy pool. This is going to be a lot more random than uniqid() which is already mostly a timestamp, adding another timestamp to this mix doesn't help at all. Remove this line of code, asap.

Checking the IP address is problematic, ip addresses change for legitimate reasons, such as if the user is behind a load balancer or TOR. The user agent check is pointless, it is like having a GET variable like ?is_hacker=False, if the attacker has the session id they probably have the user agent, and if they don't this value is really easy to brute force.

Preventing session hijacking

Unfortunately, there is no effective way to unmistakably identify a request that originates from an attacker in opposite to a genuine request. Because most properties that counter measures check like the IP address or user agent characteristics are either not reliable (IP address might change among multiple requests) or can be forged easily (e. g. User-Agent request header) and thus can yield unwanted false positives (i. e. genuine user switched IP address) or false negatives (i. e. attacker was able to successfully forge request with same User-Agent).

That’s why the best method to prevent session hijacking is to make sure an attacker cannot find out another user’s session ID. This means you should design your application and its session management that (1) an attacker cannot guess a valid session ID by using enough entropy, and (2) that there is no other way for an attacker to obtain a valid session ID by known attacks/vulerabilities like sniffing the network communication, Cross-Site Scripting, leakage through Referer, etc.

That said, you should:

  • use enough random input for generating the session ID (see session.entropy_file, session.entropy_length, and session.hash_function)
  • use HTTPS to protect the session ID during transmission
  • store the session ID in a cookie and not in the URL to avoid leakage though Referer (see session.use_only_cookies)
  • set the cookie with the HttpOnly and Secure attributes to forbid access via JavaScript (in case of XSS vulnerabilities) and to forbid transmission via insecure channel (see session.cookie_httponly and session.cookie_secure)

Besides that, you should also regenerate the session ID while invalidating the old one (see session_regenerate_id function) after certain session state changes (e. g. confirmation of authenticity after login or change of authorization/privileges) and you can additionally do this periodically to reduce the time span for a successful session hijacking attack.

Prevent session hijacking, XSS and network eavesdropping in PHP?

Session hijacking - it is when somebody knows your session identification number, provides it to the severs and, for example, logins with your priveleges.

XSS - cross site scripting, it is connected with badly filtered forms, which allow bad guys to implement their javascript code and still, for example, you cookie files.
They are 2 different forms of attack.

About preventing session hijacking some tips:
1) Set php.ini directives:

session.use_only_cookies = 1 -> for using only cookie based session ids
session.use_trans_sid = 0 -> disable showing PHPSESSID in browser url

2) About sessions

session_start();// -> starts your session. 
//Your browser will accept http header with session id and store it.
//You will be identified by this session id, usually PHPSESSID

It is looking like that:

GET / HTTP/1.1
Host: example.org
User-Agent: Mozilla Compatible (MSIE)
Accept: text/xml, image/png, image/jpeg, image/gif, */*
Cookie: PHPSESSID=1234

When session started you can provide any data to php global array $_SESSION, like

$_SESSION['var'] = 'abc';

If someone knows your PHPSESSID, he can send the same http header to the server and start using it, like he is you.

So, the best way to avoid it:

a) use session_regenerate_id() everytime you provide any important data. It will delete old session number and generate a new one.

b) save in $_SESSION you fingers: ip adress and/or browser-agent. If they differs, than - it is not you. For example:

session_start();
if (isset($_SESSION['HTTP_USER_AGENT']))
{
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
//some code
}
}
else
{
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}

c) use SSL for providing sensitive data.

Hope, you'll find it usefull.

How to prevent session hijacking with php when all pages are loaded in index.php

I think you cannot prevent the other browser to stop generating the session file with the codes that you have written so far as because with every time you will reload the page a session file will be created on the existing session file like previously your session file was sess_98765eryu again when you will reload it will generate sess_324yiuyiui by replacing the first one. So now when you will open your link in different browser a new session file be generated but it will be blank if you will login with your credentials then the data will be filled into that new session file but again your session filename will be changed although the data in it will not change. I think this is a genuine process.

And to your session hijacking what codes you have implemented i think its true and also quite normal rather you can also study more about using Securing Session INI Settings along this you can also follow some good examples here how to prevent session hijacking with php. I hope this may help you. :)

Implementing Session Hijacking prevention, properly

This is really a common problem - discussed many times before. I suggest you visit security pages such as http://owasp.com/index.php/Main_Page for a bunch of very good guides.

As for your implementation: you can also store some sort of hash that you generate first time person comes gets a session and an IP. Also I guess a good time out on cookie.

PHP Sessions Hijacking and its methods

First of all, session data is only stored on the server, so an outside client can't simply create their own session data and send it to your server.

It therefore comes down to actually guessing the session identifier of someone else and assume their identity; this is quite difficult, but not impossible. In a situation whereby an attacker can tap the network traffic between the victim and your server, it's downright impossible to stop them.

There are a few things you can adopt to make things safer, though:

  1. Use SSL; see also session.cookie_secure.
  2. Generate identifiers from a good random source, i.e. /dev/urandom on Linux machines; see also session.entropy_file.
  3. Regenerate the identifier when a user logs in or out; see also session_regenerate_id()
  4. Use HttpOnly cookies (and only cookies) to perpetuate a session identifier; see also session.use_only_cookies and session.cookie_httponly.
  5. Use strict sessions; see also session.use_strict_mode.
  6. Keep a computed hash of the user agent in the session and make sure it doesn't change, e.g.:

    $_SESSION['_agent'] = sha1($_SERVER['HTTP_USER_AGENT']);
  7. Try to reduce the lifetime of a session as short as possible and use an advanced "remember me" feature to regenerate sessions as they expire.

It's also important to know when a potential hijack has taken place and take appropriate action when that happens. You will need to keep track of which sessions belong to which user so that you can invalidate all of them when one of them has been breached.

Btw, locking the session to an IP address is tricky; some ISP's will make it seem that a user comes from various addresses or multiple users come from the same address. Either way, it might be better to keep track of the user agent, since that's less likely to change.

Session hijacking prevention...how far will my script get me? additional prevention procedures?

With the limitation of 15 miniatures you ensure that if the session hijacked, attacker can not use it for a long time, while the user leaved his/her machine or turned it off ( and has not logged off ). But what about the time that user is working and attacker has hijacked the session. Checking ip address is a good idea but there is a small limitation with it. while user doesn't have static ip address and he/she has been disconnected from the network and reconnected. A new ip address will be assigned to it. And this situation forces his session to be expired, while he is a valid user. Also this trick doesn't do anything for attackers that are in the same private LAN with valid user and they both are behind a gateway with a public ip address. because they both have same ip address in your server ( ip address of NAT or gateway ).
In my opinion what you have done is good. But it is better to make the website secure against XSS and CSRF attacks. Preventing javascript injection in client. And if it is so important to prevent any such attacks, also using ssl to be secure againt network sniffers.

How exactly does session hijacking work in PHP?

Lots of good questions, and good on you for asking them.

First.. a session is just a cookie. A 'session' is not something that's part of the HTTP stack. PHP just happens to provide some conveniences that make it easy to work with cookies, thus introducing sessions. PHP chooses PHPSESSID as a default name for the cookie, but you can choose any you want.. even in PHP you can change the session_name.

Everything an attacker has to do is grab that session cookie you're looking at, and use it in its own browser. The attacker can do this with automated scripts or for instance using firebug, you can just change the current cookie values.

So yes, if I have your id.. I can steal your session if you didn't do anything to prevent it.

However.. the hardest part for an attacker is to obtain the cookie in the first place. The attacker can't really do this, unless:

  • They have access to your computer
  • They somehow are able to snoop in on your network traffic.

The first part is hard to solve.. there are some tricks you can do to identify the computer that started the session (check if the user agent changed, check if the ip address changed), but non are waterproof or not so great solutions.

You can fix the second by ensuring that all your traffic is encrypted using HTTPS. There are very little reasons to not use HTTPS. If you have a 'logged in' area on your site, do use SSL!!

I hope this kind of answers your question.. A few other pointers I thought of right now:

  • Whenever a user logs in, give them a new session id
  • Whenever a user logs out, also give them a new session id!
  • Make sure that under no circumstances the browser can determine the value of the session cookie. If you don't recognize the cookie, regenerate a new one!


Related Topics



Leave a reply



Submit