<?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;
}
}
}
}
|