<?php 
namespace Jackbooted\Security; 
 
use \Jackbooted\Config\Cfg; 
use \Jackbooted\Forms\Request; 
use \Jackbooted\Forms\Response; 
use \Jackbooted\Util\Log4PHP; 
/** 
 * @copyright Confidential and copyright (c) 2016 Jackbooted Software. All rights reserved. 
 * 
 * Written by Brett Dutton of Jackbooted Software 
 * brett at brettdutton dot com 
 * 
 * This software is written and distributed under the GNU General Public 
 * License which means that its source code is freely-distributed and 
 * available to the general public. 
 */ 
 
class TamperGuard extends \Jackbooted\Util\JB { 
    const CHECKSUM = '_CS'; 
 
    private static $log; 
    public static $knownFields; 
 
    public static function init () { 
        self::$log = Log4PHP::logFactory ( __CLASS__ ); 
        self::$knownFields =  [ 'XDEBUG_SESSION_START', 'XDEBUG_PROFILE' ]; 
    } 
 
    public function __construct () { 
        parent::__construct(); 
    } 
 
    public static function known ( $key ) { 
        self::$knownFields[] = $key; 
    } 
 
    public static function del ( Response $response ) { 
        $response->del ( self::CHECKSUM ); 
    } 
 
    public static function add ( Response $response ) { 
        $keyList =  []; 
        $valList =  []; 
 
        foreach ( $response as $key => $val ) { 
            if ( is_array ( $val ) ) { 
                foreach ( $val as $key1 => $val1 ) { 
                    if ( is_array ( $val1 ) ) continue; 
                    $keyList[] = '[' . $key . '][' . $key1 . ']'; 
                    $valList[] = $val1; 
                } 
            } 
            else { 
                if ( ( $loc = strpos ( $key, '[' ) ) !== false ) { 
                    $keyList[] = '[' . substr ( $key, 0, $loc ) . ']' . substr ( $key, $loc ); 
                } 
                else { 
                    $keyList[] = '[' . $key . ']'; 
                } 
                $valList[] = $val; 
            } 
        } 
 
        $flatKeyList = join ( ',', $keyList ); 
        $hash = md5 ( $flatKeyList . join ( '', $valList ) ); 
        $response->set ( self::CHECKSUM,  [ $flatKeyList, $hash ] ); 
    } 
 
 
    public static function check ( Request $request ) { 
        if ( ( $formVarLen = $request->count() ) == 0 ) return true; 
        foreach ( $request as $key => $val ) { 
            if ( in_array ( $key, self::$knownFields ) ) { 
                $formVarLen --; 
            } 
        } 
        if ( $formVarLen <= 0 ) return true; 
 
        if ( ( $checksum = $request->getVar ( self::CHECKSUM ) ) == '' ) { 
            $request->clear (); 
            if ( Cfg::get( 'jb_tamper_detail', false ) ) { 
                return 'Checksum Variable Missing from the request.'; 
            } 
            else { 
                self::$log->error ( 'Checksum Variable Missing from the request: ' . $_SERVER['SCRIPT_NAME'] ); 
                return false; 
            } 
        } 
        else if ( ! is_array ( $checksum ) ) { 
            $request->clear (); 
            if ( Cfg::get( 'jb_tamper_detail', false ) ) { 
                return 'Checksum Variable not an array.'; 
            } 
            else { 
                self::$log->error ( 'Checksum Variable not an array: ' . $_SERVER['SCRIPT_NAME'] ); 
                return false; 
            } 
        } 
        else if ( count ( $checksum ) != 2 ) { 
            $request->clear (); 
            if ( Cfg::get( 'jb_tamper_detail', false ) ) { 
                return 'Checksum Variable not 2 elements.'; 
            } 
            else { 
                self::$log->error ( 'Checksum Variable not 2 elements: ' . $_SERVER['SCRIPT_NAME'] ); 
                return false; 
            } 
        } 
        else { 
            if ( ! empty ( $checksum[0] ) ) { 
                $keys = explode ( ',', $checksum[0] ); 
                $allVariablesJoined = $checksum[0]; 
                foreach ( $keys as $key ) { 
                    $allVariablesJoined .= $request->getRaw ( $key ); 
                } 
            } 
            else { 
                $allVariablesJoined = ''; 
            } 
 
            if ( md5 ( $allVariablesJoined ) != $checksum[1] ) { 
                $request->clear (); 
                if ( Cfg::get( 'jb_tamper_detail', false ) ) { 
                    return 'Checksum failed md5('.$allVariablesJoined.')<>'. $checksum[1]; 
                } 
                else { 
                    self::$log->error ( 'The checksum has failed. The request variables have been tampered: ' . $_SERVER['SCRIPT_NAME'] ); 
                    return false; 
                } 
                self::$log->error ( 'The checksum has failed. The request variables have been tampered. ' . $_SERVER['SCRIPT_NAME'] ); 
            } 
            else { 
                return true; 
            } 
        } 
    } 
}
 
 |