Validating PHP User Sessions
Session Security
First of all, because of the public computer risk, your design should be such that the logout button is always visible when logged in, so that the user can easily log out at any time. Your PHP configuration options (or custom script) should be set so that sessions will ??timeout?? after approximately 20 minutes of inactivity. If you don??t have access to the PHP configuration options on shared hosting and it doesn??t timeout after 20 minutes or so, then you should store the ??last access time?? in the session itself and destroy the session if it is accessed after a time of inactivity. Also, if you manually set a cookie (using a custom script) you should set it so that it is destroyed when the browser window is closed not by an expiration date (PHP??s session_start() sets the cookie this way by default). If you do need to set an expiration date, such as for a ??remember me?? function, it should not be set by default, and should only be used when the user explicitly checks a box that says ??remember me?? since only the user will know whether or not they are on a public computer.
Secondly, in order to protect your session as much as possible, you need to find as many unique aspects of the user??s computer as you can find, and verify that they stay the same across all page requests. The most common security precaution here is to verify that the IP address stays the same. It is possible that a hacker could be at the same IP address as the valid user, or perhaps even IP spoof, but it is more unlikely. However, depending on your needs for security versus ease-of-use, and whether or not you need sessions to span hours or days (for ??remember me?? functions) you need to bring this into balance with the fact that a user??s IP address can potentially change throughout a session, particularly with large dial-up companies like AOL, etc. This means that the valid user may potentially get bumped. For this reason, applications like the open source phpbb bulletin board only verify the first 6 characters of the IP address by default, to make it less likely that a user will get bumped from an ISP generated IP change.
It would be nice if every browser sent out a unique 32-64 character id to identify it that JavaScript would not be allowed to access so that the only hackers that could get through would be the ones who were able to listen to the site??s traffic. However, until that time, the next best thing that I have found, which I use in my own code, is to verify that the user maintains the same user-agent across all page requests. The user-agent environment variable changes depending on browser, version, and operating system, etc., especially in IE. It is entirely possible for a hacker to have the same user-agent and/or to spoof it if they know what it is. So, it is, clearly, not even close to being bullet-proof. However, it is simply one extra step that can be taken to help keep hackers out, and combined with an IP check, it??s a step that makes it just a tiny bit less likely for someone to get through.
Finally, one of the most important things is to make sure you validate user-input so that hackers can??t compromise your sessions using JavaScript. If you have a site that allows users to fill out forms to enter text onto the site, if at all possible, you should try to avoid allowing HTML to be entered into the forms. You can either strip out all HTML tags using the strip_tags() method built into PHP, or you can change HTML markup to its HTML equivalent (e.g. < becomes <), which can also be done easily using the htmlentities() method built into PHP. If you must allow HTML, then you should try to make sure that event handlers and <script> tags are not allowed into the content, which requires more difficult parsing.
Now, it is important to know that even with all of the above, the site is still not ??safe??. For one, unless you are using SSL on the site, the session identifier, the IP address, and the user-agent are all being sent to the server in plain text. This means that a good hacker, listening to the server traffic, will still be able to hack into the system fairly easily. If the data you are protecting is important, then your best course of action is, on top of taking all the previously mentioned precautions, enabling SSL on the server so that all data exchange is encrypted.
On the next page, I have provided a simplified example of doing a manual timeout as well as verifying IP address and user-agent to validate a session. It is my recommendation that if the credentials don??t match, that you immediately destroy the session to ensure that the hacker can??t keep trying different things after finding a valid session identifier. This will log out the valid user, but is worthwhile to do so.