226 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 226 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s Next, a couple of tests are made. These check whether the value returned by session_ id() is not FALSE, in which case a session does exist (and that value will be the session ID), and whether a cookie exists with the name returned by session_name(). If either of these cases is TRUE, then it’s necessary to destroy any session cookie that may exist on the user’s computer. This is done by issuing a setcookie() call with the same details that will have been used to create it, but with an expiry date of 30 days in the past. Being a month ago, the browser will automatically delete the cookie as having expired already. Any time in the past will do. I chose a month just to be sure. Finally, the session_destroy() function is called and the value returned by it is returned by the plug-in. The @ symbol prefacing the call is there to suppress any error messages that might occur, particularly if the call fails due to the session already having been destroyed, or the plug-in having been called with no session in existence. How to Use It To terminate a session, place a call to this plug-in before any text is output, like this: $result = PIPHP_CloseSession(); The variable $result will have the value TRUE if the call succeeded, otherwise it will be FALSE. You generally don’t need to worry if the call fails as it usually only happens if there is no session to close, which is the situation you wanted anyway. The Plug-in function PIPHP_CloseSession() { $_SESSION = array(); if (session_id() != "" || isset($_COOKIE[session_name()])) setcookie(session_name(), '', time() - 2592000, '/'); return @session_destroy(); } Secure Session If there’s a way a hacker can break into your web site, you can bet they’ll try. One trick they use is to hijack PHP sessions. This might be achieved in different ways, but the main security hole is when a hacker locates a site that passes the session ID in a GET URL tail. Given this information, a hacker could start a session and then pass on the URL (including the session ID) in spam or other links. They could then go back and look for evidence of any of these links having being followed and, if the user hasn’t logged out, they may be able to hijack the session and assume the user’s identity. But by using this simple plug-in, tricks of that nature are rendered completely useless. Figure 9-8 shows a session that is opened with PIPHP_OpenSession() and then tested for security with this plug-in. 68 C h a p t e r 9 : M y S Q L , S e s s i o n s , a n d C o o k i e s 227 C h a p t e r 9 : M y S Q L , S e s s i o n s , a n d C o o k i e s 227 About the Plug-in This plug-in checks whether a session appears to not be secure, and if not, it closes the session. It does not require any arguments. Variables, Arrays, and Functions $ipnum String variable containing the IP number of the current user $agent String variable containing the browser User Agent string of the current user How It Works In plug-in 65, Create Session, I mentioned the session variables containing the IP number and browser User Agent string which are set up when a session is created using the PIPHP_ CreateSession() plug-in. Well, this plug-in is where they come into use. What it does is check the current browser’s User Agent and IP number against those saved in the session variables. If either is different, the session is closed using PIPHP_ CloseSession() and a value of FALSE is returned. This is done to ensure that only the user who was online and present when the session was created can continue to use it, neatly avoiding any attempts by hackers to either poison a new session or take over an existing one. If the strings do match, it is assumed the user is the same person, and so TRUE is returned. Oh, and if there appears to be no session active (tested by seeing whether $_SESSION['ipnum'] has a value), then FALSE is returned. How to Use It To use the function, you would probably call it immediately after a call to PIPHP_ OpenSession(), like this: if (!PIPHP_SecureSession()) { // Login code goes here to log the // user back into a secure session } It may be extra work but it’s worth implementing this feature for your users’ protection. FIGURE 9-8 This plug-in helps secure against hackers hijacking a user’s session. 228 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 228 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s The Plug-in function PIPHP_SecureSession() { $ipnum = getenv("REMOTE_ADDR"); $agent = getenv("HTTP_USER_AGENT"); if (isset($_SESSION['ipnum'])) { if ($ipnum != $_SESSION['ipnum'] || $agent != $_SESSION['agent']) { PIPHP_CloseSession(); return FALSE; } else return TRUE; } else return FALSE; } Manage Cookie Cookies are a great way to provide additional functionality to your users, and contrary to the impression that some news reports might give, they have other more beneficial functions besides tracking users for advertising purposes. For example, you can save a token representing a person’s username and password in a cookie to keep them logged in to a site, something PHP sessions do unless cookies are disabled, in which case the query string is used for this. Cookies are also great for associating variables directly with a user via the browser they use. You could use them, for example, to note that a user has already completed a questionnaire on your site and should not be asked again. Figure 9-9 shows the cookie Test being given the value 3.1415927 by this plug-in. The cookie is sent to the browser but has not been returned by it because cookies are only transferred in the header exchange that takes place before the contents of a web page are transferred. After reloading the page, the cookie is passed back to the web server by the browser, and so the cookie returns the assigned value, as the figure inset shows. FIGURE 9-9 This plug-in lets you set, read, and delete cookies in a user’s browser. 69 C h a p t e r 9 : M y S Q L , S e s s i o n s , a n d C o o k i e s 229 C h a p t e r 9 : M y S Q L , S e s s i o n s , a n d C o o k i e s 229 About the Plug-in This plug-in sets, reads, and deletes cookies. It requires the following arguments: • $action The action to take: set, read, or delete • $cookie The name to use for the cookie • $value The value to give the cookie • $expire The number of seconds after which the cookie will expire • $path The path to the cookie on the server Variables, Arrays, and Functions • None How It Works This plug-in comprises three parts, separated by the case qualifiers of a switch statement, based on the value of $action after converting it to lowercase. If the value is set, then the number of seconds passed in $expire is added to the value returned by time() to create a timestamp $expire seconds into the future. Or, if $expire is NULL, it is left alone. When this value is passed to the setcookie() function, the expiry date of that cookie will either be $expire seconds in the future, or if $expire is NULL, the cookie will expire when the browser is closed. Next, the setcookie() call is made, passing the name of the cookie in $cookie, the value to assign to it in $value, the value in $expire, and the path to the server in $path. The latter defines the scope over which a cookie is valid. For example, if $path has the value /news/, then only that folder (and its subfolders) can access the cookie. But if it is /, then the cookie can be accessed by all folders on that web domain. If $action has the value read, then, using the function isset(), a test is made to see whether a cookie of the name stored in $cookie exists. If so, that value is returned, otherwise FALSE is returned. If $action contains the word delete, then, using isset(), if the cookie with the name in $cookie is found to exist, the cookie is resent to the browser using its current name and an expiry date of a month in the past, as calculated by subtracting 30 days’ worth of seconds from the value returned by a call to time(). This has the effect of making the cookie instantly expire. If $action contains none of the preceding words, then FALSE is returned. How to Use It To set a browser cookie, you could use code such as this: $cookie = 'Test'; $val = '3.1415927'; $exp = 300; $path = '/'; $result = PIPHP_ManageCookie('set', $cookie, $val, $exp, $path); 230 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 230 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s If $result has a value of TRUE, then the cookie was successfully set. To then read back the value of a cookie (which would have to occur the subsequent time the page loads), you would then use code like this: $result = PIPHP_ManageCookie('read', $cookie, NULL, NULL, NULL); Upon success, $result will contain the contents of the cookie; otherwise, it will have the value FALSE. To delete the cookie, issue the following command: $result = PIPHP_ManageCookie('delete', $cookie, NULL, NULL, NULL); Successful deletion will give $result a value of TRUE, otherwise it will be FALSE. Possible reasons for the call failing are if the cookie is already deleted or it doesn’t exist. The Plug-in function PIPHP_ManageCookie($action, $cookie, $value, $expire, $path) { switch(strtolower($action)) { case 'set': if ($expire) $expire += time(); return setcookie($cookie, $value, $expire, $path); case 'read': if (isset($_COOKIE[$cookie])) return $_COOKIE[$cookie]; else return FALSE; case 'delete': if (isset($_COOKIE[$cookie])) return setcookie($cookie, NULL, time() - 60 * 60 * 24 * 30, NULL); else return FALSE; } return FALSE; } Block User by Cookie If you’ve ever done any chat-related programming, you’ll have come across trolls: downright nasty individuals who you don’t want on your site. You may even have banned them via their IP address. If you have, you may also have encountered the problem of these individuals restarting their web connections to obtain new IP addresses with which to harass you and your users. You will also possibly have noticed that some “bad” users share their IP address with “good” ones, generally because they work in the same building and share a DSL or similar Internet connection. So blocking a “bad” user by IP would also block “good” ones. But there is a way you can ban unwanted users more permanently and precisely, and that’s to leave a cookie on their computer, as this plug-in does. For example, Figure 9-10 shows 70 . variables containing the IP number and browser User Agent string which are set up when a session is created using the PIPHP_ CreateSession() plug- in. Well, this plug- in is where they come into use. What. Functions $ipnum String variable containing the IP number of the current user $agent String variable containing the browser User Agent string of the current user How It Works In plug- in 65, Create Session,. besides tracking users for advertising purposes. For example, you can save a token representing a person’s username and password in a cookie to keep them logged in to a site, something PHP sessions