Session hijacking can occur on standard HTTP pages. It can also occur when SSL (HTTPS) isn’t implemented correctly. There are measures you can take to make session hijacking difficult, if not impossible, for all but the most experienced hackers.
I’ll go over these briefly and let you make up your mind how much security you need. It’s easy to get complacent when you don’t understand the risks.
Probably the most important thing is to make sure PHP is using only cookies for sessions. If a session ID is included in a URL, simply posting the complete URL somewhere invites session hijacking attempts. Also, session regeneration techniques would break the back button because the URL would change each time.
Session cookies aren’t immune to interception, but they can be made worthless to anyone else. Human beings can’t move as fast as sessions can be changed. Session files must be stored in a server location only accessible by one server user and one website at a time. Session files can be manipulated otherwise (think shared hosting), thus altering those session cookies.
When checking the PHP runtime settings, this flag should always be set to “1” (without the quotes). You shouldn’t rely on it already being set. You should make sure you set it when you’re configuring your application.
One thing to be aware of is that you have to set the session cookie name before you can set the parameters. You also have to use the session name when destroying the session. While this flag is disputed as effective against XSS among developers, any extra protection measure is worth implementing.
When using the cookie-only approach to sessions, the web browser’s back button will function normally. While it may seem like overkill, you can regenerate the session ID on every page load. An attacker would have to be able to duplicate it from the outside, using HTTP headers, in a small window of opportunity every time.
The proper way to do it is to set the flag to true (wiping out session data) upon a successful login and setting it to false on every occasion after that.
It can’t be done using PHP only and it requires storing certain HTTP environment variables and comparing them with what’s being received with every page load. IP addresses and user agents aren’t reliable because both can change from one page load to the next.
This technique isn’t something I can recommend even though a few prominent websites are using it. (It’s how they can tell you’re using a different web browser or computer when logging in, even at the same IP address.)
If you have a membership site of some kind, your members have to log on or log in, right? They obviously know what their credentials are. If you have a secure login form of some kind, you can create pages that require the same parameters when someone posts something. By doing so, you can make session hijacking useless.
The key here is that the member should have a password manager. Most of the major web browsers have add-ons like LastPass that will store the data securely. There are also specific programs for various operating systems as well, like KeePass Password Safe. These things are free!
If nothing else, most modern web browsers will let you store your data within the web browsers themselves. It’s something I can only recommend if your web browser isn’t being used by anyone else.
You’re going to get a percentage of people who won’t read the instructions and another percentage who won’t read them well enough to understand what they mean. You need to be ready and offer other avenues like contact forms, sticky posts or whatever else you can think of to minimize support requests.
Using SSL is the only way to insure against session hijacking and even then it can still be done. The SSL secure flag must be set with the session cookie or it won’t be encrypted by the SSL handshake.
Regardless of what method you use, with or without SSL, you should always store confidential information in an encrypted state. That way, even if an attacker should break in, minimal damage can occur and the rest of the private data stays private.
Originally published in August of 2013. Updated for readability and minor corrections.