The authorization code that checks the authentication control session variables, shown in Example 9-11, can be written to a separate file and included with each protected page using the include
directive. This saves having to rewrite the code for each page that requires authorization.
Example 9-11 begins by initializing the session and calculating two Boolean flags. The first flag $notAuthenticated
is set to true
if the session variable $authenticatedUser
isn't set. The second flag $notLoginIp
is set to true
only if the session variable $loginIpAddress
is set and has the same value as the IP address of the client that sent this request. The IP address of the client that sent the request is available to scripts in the server environment variable $REMOTE_ADDR
. Unlike with environment variables, PHP doesn't overwrite $REMOTE_ADDR
by a GET
or POST
variable with the same name.
Both the $notAuthenticated
flag and the $notLoginIp
flag are tested, and if either is true
, an appropriate $loginMessage
is set and registered with the session, and then the Location:
header field is sent with the HTTP response to relocate the browser back to the login script. The two cases are separated, because the script might be enhanced to record more information about the possible hijack attempt and even to destroy the session.
Example 9-11. Code that checks the authenticated state from the session variables
<?php session_start( ); $loginScript = "example.9-8.php"; // Set a boolean flag to check if // a user has authenticated $notAuthenticated = !isset($HTTP_SESSION_VARS["authenticatedUser"]); // Set a boolean flag to true if this request // originated from the same IP address // as the one that created this session $notLoginIp = isset($HTTP_SESSION_VARS["loginIpAddress"]) && ($HTTP_SESSION_VARS["loginIpAddress"] != $REMOTE_ADDR); // Check that the two flags are false if($notAuthenticated) { // The request does not identify a session session_register("loginMessage"); $loginMessage = "You have not been authorized to access the " . "URL $REQUEST_URI"; // Re-locate back to the Login page header("Location: " . $loginScript); exit; } else if($notLoginIp) { // The request did not originate from the machine // that was used to create the session. // THIS IS POSSIBLY A SESSION HIJACK ATTEMPT session_register("loginMessage"); $loginMessage = "You have not been authorized to access the " . "URL $REQUEST_URI from the address $REMOTE_ADDR"; // Re-locate back to the Login page header("Location: " . $loginScript); exit; } ?>
To use the code developed in Example 9-11 to protect a page, we only need to include the file containing the code. If we saved Example 9-11 to auth.inc, protecting a page is easy:
<?php include("auth.inc"); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <html> ... <h2>Your Credit Card details</h2> ... <p><a href="example.9-10.php">Logout</a> ... </html>
As discussed in Chapter 4, including files with the .inc extension presents a security problem. If the user requests the include file, the source of the include file is shown in the browser.
There are three ways to address this problem:
-
Store the include files outside the document tree of the Apache web server installation. For example, store the include files in the directory /usr/local/include/php and use the complete path in the
include
directive. -
Use the extension .php instead of .inc. In this case, the include file is interpreted by the PHP script engine and produces no output because it contains no main body.
-
Configure Apache so that files with the extension .inc can't be retrieved.