PHP Classes

File: handlers/security.inc.php

Recommend this page to a friend!
  Classes of Colin McKinnon   Stackable PHP Session Handler   handlers/security.inc.php   Download  
File: handlers/security.inc.php
Role: Class source
Content type: text/plain
Description: Add additional security checks to the session management
Class: Stackable PHP Session Handler
Store session data with multiple session handlers
Author: By
Last change:
Date: 8 years ago
Size: 2,853 bytes
 

Contents

Class file image Download
<?php
/**
 * Perform security checks on the session requests
 * You may want to fine tune the network validation routines here
 * e.g. being more specific for LAN traffic, less for mobile
 */
/**
 * note that we need to store data inside the session, and that means we need
 * to use a serialization method accessible from the PHP code
 * and *that* means we need at least v5.5.4
 */

if (version_compare(PHP_VERSION, '5.5.4') >=0) {
   
ini_set('session.serialize_handler', 'php_serialize');
} else {
   
trigger_error("Security session handler requires PHP 5.5.4 or later", E_USER_ERROR);
}

class
securitySession extends stackSess {
    function
open($save_path, $name)
    {
        if (
$this->shStackNext) {
                        return
$this->shStackNext->open($save_path, $name);
        } else {
           
trigger_error("Security session handler has no storage capability", E_USER_ERROR);
            return
false;
        }
    }
    function
read($session_id)
    {
       
// we don't allow an expired session to be read
       
if ($this->shStackNext) {
           
$session_str=$this->shStackNext->read($session_id);
           
// above required to populate lastAccess...
           
$lastAccess=$this->shStackNext->lastAccessed();
           
$max_ttl=ini_get('session.cookie_lifetime');
            if (
$max_ttl && time()-$lastAccess>$lastAccess) {
               
$this->logit("Session accessed after expiry", E_USER_NOTICE);
               
$this->destroy($session_id);
                return
'';
            }
           
$session_sr=$this->securityCheck($session_id, $session_str);
            return
$session_str;
        }
        return
false;
    }
    function
create_sid($newlyCreatedSid=false)
    {
        if (
is_callable(array($this->shStackNext,'create_sid'))) {
           
// we always send down the stack
           
$newlyCreatedSid=$this->shStackNext->create_sid($newlyCreatedSid);
        }
        return
$newlyCreatedSid;
    }
    function
securityCheck($session_id, $session_str)
    {
       
$sess=unserialize($session_str);
        if (!isset(
$sess['securityCheck'])) {
           
// data is not yet populated - populate now
           
$sess['securityCheck']=array(
               
'user_agent'=>$_SERVER['HTTP_USER_AGENT'],
               
'c_ip'=>$_SERVER["REMOTE_ADDR"]
            );
            return
serialize($sess);
        }
       
$stored_ua=get_browser($sess['securityCheck']['user_agent'], true);
       
$current_ua=get_browser(null, true);
        if (
$stored_ua['platform'] != $current_ua['platform']
            ||
$stored_ua['parent'] != $current_ua['parent']) {
           
$this->logit("Details changed mid session " . var_export($sess['securityCheck'],true), E_USER_NOTICE);
            return
false;
        }
        if (!
$this->compareIP($sess['securityCheck']['c_ip'], $_SERVER["REMOTE_ADDR"])) {
           
$this->logit("Client network changed from $sess[securityCheck][c_ip]", E_USER_NOTICE);
            return
false;
        }
        return
$session_str;
    }
   
// if you don't get an exact match, you might want to
    // compare netmasks, or the Organisation in the whois, or the ASN
   
function compareIP($ip1, $ip2)
    {
        if (
$ip1==$ip2 || !$ip1 || !$ip2) {
            return
true;
        }
    }
}