Improving Session Security


Because important information is normally stored in a session (as opposed to a cookie), security becomes more of an issue. Remember that with sessions there are two considerations: the session ID, which is a reference point to the session data, and the session data itself, stored on the server. A malicious person is far more likely to hack into a session through the session ID than the data on the server, so I'll focus on that side of things here.

Storing the session ID in a cookie is considered the more secure method of using sessions, as opposed to passing the session ID along in URLs or storing it in hidden form inputs. Those alternatives are less secure because the session could easily be hijacked by another user, as you already witnessed. If I can learn another user's session ID, I can easily trick a server into thinking that it is my session ID. At that point I have effectively taken over the original user's entire session and may have access to their data. So storing the session ID in a cookie makes it somewhat harder to steal.

One method of preventing hijacking is to store some sort of user identifier in the session, and then to repeatedly double-check this value. The HTTP_USER_AGENTa combination of the browser and operating system being usedis a likely candidate for this purpose. This adds a layer of security in that I could only hijack another user's session if I am running the exact same browser and operating system. For example, a login page would have

 $_SESSION['agent'] = $_SERVER  ['HTTP_USER_AGENT]; 

Then subsequent pages would check the stored HTTP_USER_AGENT against the user's HTTP_USER_AGENT (which should be the same).

 if ($_SERVER['HTTP_USER_AGENT'] !=   $_SESSION['agent]) {    /* The session has probably    been hijacked! */ } 

As a demonstration of this, I'll modify the examples one last time. While I'm focusing on security, I'll encrypt the $_SERVER['HTTP_USER_AGENT'] information using the md5() function to make it harder to fake.

Preventing Session Fixation

Another specific kind of session attack is known as session fixation. This is where one user specifies the session ID that another user should use. This session ID could be randomly generated or legitimately created. In either case, the real user will go into the site using the fixed session ID and do whatever. Then the malicious user can access that session because they know what the session ID is. You can help protect against these types of attack by changing the session ID. The session_regenerate_id() does just that, providing a new session ID to refer to the current session data. You can use this function should anything of consequence change during a user's session.


To use sessions more securely

1.

Open login.php (refer to Script 9.14) in your text editor.

2.

Delete the ini_set() line and remove the reference to SID (Script 9.15).

Script 9.15. This final version of the login.php script also stores an encrypted form of the user's HTTP_USER_AGENT (the browser and operating system of the client) in a session.


For security purposes, I'll revert to using cookies to store the session ID. I also no longer need to append SID to the header() redirection URL.

3.

After assigning the other session variables, store the HTTP_USER_AGENT.

 $_SESSION['agent'] = md5($_SERVER  ['HTTP_USER_AGENT]); 

The HTTP_USER_AGENT is part of the $_SERVER array (you may recall using it way back in Chapter 1, "Introduction to PHP"). It will have a value like Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322). This variable is run through the md5() function, which will turn it into a 32-character hexadecimal hash (although it's just easier to say that the data is encrypted).

4.

Save the file and upload to your Web server.

5.

Open loggedin.php (Script 9.11) in your text editor.

6.

Change the !isset($_SESSION['user_id']) conditional to (Script 9.16)

 if (!isset($_SESSION['agent'])   OR ($_SESSION ['agent] != md5  ($_SERVER['HTTP_USER_AGENT])) ) { 

Script 9.16. This loggedin.php script now confirms that the user accessing this page has the same HTTP_USER_AGENT as they did when they logged in.


This conditional checks for two things. First, it sees if the $_SESSION['agent'] variable is not set (this part is just as it was before, although agent is being used instead of user_id). The second part of the conditional checks if the md5() version of $_SERVER['HTTP_USER_AGENT'] does not equal the value stored in $_SESSION['agent']. If either of these conditions are true, the user will be redirected.

7.

Save this file, upload to your Web server, and test in your Web browser by logging in (Figure 9.22).

Figure 9.22. You cannot tell any difference by running the application, but this final version of the login system is more secure. Specifically, it helps to prevent session hijacking.


Tips

  • For critical uses of sessions, require the use of cookies and transmit them over a secure connection, if at all possible. You can even set PHP to only use cookies by setting session.use_only_cookies to 1 (as of PHP 4.3).

  • If you are using a server shared with other domains, changing the session.save_path from its default settingwhich is accessible by all usersto something more local will be more secure.

  • On the server side of security, the session data itself can be stored in a database rather than a text file. This is a more secure, but more programming-intensive, option.

  • The user's IP address (the network address from which the user is connecting) is not a good unique identifier, for two reasons. First, a user's IP address can, and normally does, change frequently (ISP's dynamically assign them for short periods of time). Second, many users accessing a site from the same network (like a home network or an office) could all have the same IP address.




    PHP and MySQL for Dynamic Web Sites. Visual QuickPro Guide
    PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide (2nd Edition)
    ISBN: 0321336577
    EAN: 2147483647
    Year: 2005
    Pages: 166
    Authors: Larry Ullman

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net