/**
  * Returns an instance of StringValidationRule constructed with a regex
  * pattern for validating Credit Card Numbers obtained from the ESAPI
  * SecurityConfiguration.
  *
  * @return object object of type StringValidationRule.
  */
 private function _getCCRule()
 {
     global $ESAPI;
     $config = ESAPI::getSecurityConfiguration();
     $pattern = $config->getValidationPattern(self::CREDIT_CARD_VALIDATOR_KEY);
     $ccr = new StringValidationRule('CreditCardValidator', $this->encoder, $pattern);
     $ccr->setMaximumLength(19);
     $ccr->setAllowNull(false);
     return $ccr;
 }
 /**
  * Creates a new instance of EnterpriseSecurityException that includes a
  * root cause.
  *
  * @param string $userMessage The message displayed to the user
  * @param string $logMessage  the message logged
  */
 public function __construct($userMessage = '', $logMessage = '')
 {
     $cause = 0;
     if (empty($userMessage)) {
         $userMessage = null;
     }
     parent::__construct($userMessage);
     $this->logMessage = $logMessage;
     $this->logger = ESAPI::getAuditor("EnterpriseSecurityException");
     if (!ESAPI::getSecurityConfiguration()->getDisableIntrusionDetection()) {
         ESAPI::getIntrusionDetector()->addException($this);
     }
 }
Esempio n. 3
0
<?php

/**
 * OWASP Enterprise Security API (ESAPI)
 *
 * This file is part of the Open Web Application Security Project (OWASP)
 * Enterprise Security API (ESAPI) project.
 *
 * PHP version 5.2
 *
 * LICENSE: This source file is subject to the New BSD license.  You should read
 * and accept the LICENSE before you use, modify, and/or redistribute this
 * software.
 *
 * @category  OWASP
 * @package   ESAPI
 * @author    Andrew van der Stock <*****@*****.**>
 * @author    Mike Boberski <*****@*****.**>
 * @copyright 2009-2011 The OWASP Foundation
 * @license   http://www.opensource.org/licenses/bsd-license.php New BSD license
 * @version   SVN: $Id$
 * @link      http://www.owasp.org/index.php/ESAPI
 */
error_reporting(E_ALL | ~E_STRICT);
require_once __DIR__ . '/../src/ESAPI.php';
ESAPI::getSecurityConfiguration(__DIR__ . '/testresources/ESAPI.xml');
session_start();
// For HTTPUtilities;
 /**
  * Implements corresponding isValidXX logic.
  *
  * @param string $context   Please see corresponding isValidXX description.
  * @param string $input     Please see corresponding isValidXX description.
  * @param int    $maxBytes  Please see corresponding isValidXX description.
  * @param bool   $allowNull Please see corresponding isValidXX description.
  *
  * @return does not return a value.
  * @throws ValidationException thrown if input is invalid.
  * @throws IntrusionException thrown if intrusion is detected.
  */
 private function _assertValidFileContent($context, $input, $maxBytes, $allowNull)
 {
     if (!is_string($context)) {
         $context = 'Validate File Content';
     }
     if (!is_string($input) && $input !== null) {
         throw new ValidationException("{$context}: Input required", "Input was not a string or NULL: context={$context}", $context);
     }
     if (!is_numeric($maxBytes) || $maxBytes < 0) {
         $this->_auditor->warning(ESAPILogger::SECURITY, false, 'assertValidFileContent expected $maxBytes as positive integer.' . ' Falling back to AllowedFileUploadSize.');
         $maxBytes = null;
     }
     if ($input === null || $input == '') {
         if ($this->allowNull) {
             return null;
         }
         throw new ValidationException("{$context}: Input required", "Input required: context={$context}", $context);
     }
     $config = ESAPI::getSecurityConfiguration();
     $esapiMaxBytes = $config->getAllowedFileUploadSize();
     $charEnc = mb_detect_encoding($input);
     $inputLen = mb_strlen($input, $charEnc);
     if ($inputLen > $esapiMaxBytes) {
         throw new ValidationException("{$context}: Invalid file content. Size must not exceed " . "{$esapiMaxBytes} bytes.", "Invalid file content. Input ({$inputLen} bytes) exceeds " . "AllowedFileUploadSize ({$esapiMaxBytes} bytes.)", $context);
     }
     if ($maxBytes !== null && $inputLen > $maxBytes) {
         throw new ValidationException("{$context}: Invalid file content. Size must not exceed " . "{$maxBytes} bytes.", "Invalid file content. Input ({$inputLen} bytes) exceeds " . "maximum of ({$esapiMaxBytes} bytes.)", $context);
     }
     return null;
 }
Esempio n. 5
0
 /**
  * Private constructor ensures CodecDebug can only be instantiated privately.
  * Stores boolean true in $_enabled if SepcialDebugging is enabled.  This object
  * will only produce output if $_enabled is true.
  * 
  * @return null
  */
 private function __construct()
 {
     $this->_enabled = ESAPI::getSecurityConfiguration()->getSpecialDebugging();
 }
Esempio n. 6
0
 /**
  *  Helper function.
  *
  *  Configures Apache's Log4PHP RootLogger based on values obtained from the
  *  ESAPI properties file.  All instances of Log4PHP Logger will inherit the
  *  configuration.
  *
  *  @return does not return a value.
  */
 private static function _initialise()
 {
     self::$_initialised = true;
     $secConfig = ESAPI::getSecurityConfiguration();
     $logLevel = $secConfig->getLogLevel();
     // Patterns representing the format of Log entries
     // d date, p priority (level), m message, n newline
     $dateFormat = $secConfig->getLogFileDateFormat();
     $logfileLayoutPattern = "%d{{$dateFormat}} %m %n";
     // LogFile properties.
     $logFileName = $secConfig->getLogFileName();
     $maxLogFileSize = $secConfig->getMaxLogFileSize();
     $maxLogFileBackups = $secConfig->getMaxLogFileBackups();
     // LogFile layout
     $logfileLayout = new LoggerLayoutPattern();
     $logfileLayout->setConversionPattern($logfileLayoutPattern);
     // LogFile RollingFile Appender
     $appenderLogfile = new LoggerAppenderRollingFile('ESAPI LogFile');
     $appenderLogfile->setFile($logFileName, true);
     $appenderLogfile->setMaxFileSize($maxLogFileSize);
     $appenderLogfile->setMaxBackupIndex($maxLogFileBackups);
     $appenderLogfile->setLayout($logfileLayout);
     if ($logLevel !== 'OFF') {
         $appenderLogfile->activateOptions();
     }
     // Get the RootLogger and reset it, before adding our Appenders and
     // setting our Loglevel
     $rootLogger = Logger::getRootLogger();
     $rootLogger->removeAllAppenders();
     $rootLogger->addAppender($appenderLogfile);
     $rootLogger->setLevel(self::_convertESAPILeveltoLoggerLevel($logLevel));
 }
Esempio n. 7
0
 /**
  * Helper method uses the supplied parameters to construct a pattern for
  * preg_match and which attempts to model log entries.  It is important to
  * note that if changes are made to the format of log entries {@see
  * DefaultLogger::log()} then this method will need to be modified
  * accordingly.
  *
  * @param  $level string uppercase log level.
  * @param  $type string uppercase log entry type.
  * @param  $success boolean true for a success log event, false otherwise.
  * @param  $msg string log message as passed to the DefaultLogger method.
  * @param  $exceptionClassName string optional class name of an exception
  *         passed to DefaultLogger methods.
  *
  * @return string pattern (incl. terminators) for preg_match().
  */
 private function getExpected($level, $type, $success, $msg, $exceptionClassName = null)
 {
     $date = '[0-9-]{10,10} [0-9:]{8,8} [+-][0-9:]{5,5}';
     $success = $success ? '-SUCCESS' : '-FAILURE';
     $appName = ESAPI::getSecurityConfiguration()->getLogApplicationName() === true ? ' ' . ESAPI::getSecurityConfiguration()->getApplicationName() : '';
     $name = __CLASS__;
     $serverName = '((?:(?:[0-9a-zA-Z][0-9a-zA-Z\\-]{0,61}[0-9a-zA-Z])\\.)*[a-zA-Z]{2,4}|[0-9a-zA-Z][0-9a-zA-Z\\-]{0,61}[0-9a-zA-Z]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))';
     $localSocket = "{$serverName}:[0-9]{1,5}";
     $username = '******';
     $remoteAddr = '([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|UnknownRemoteHost)';
     $sessionID = '([0-9]{1,7}|SessionUnknown)';
     if ($exceptionClassName !== null) {
         $msg .= " exception '{$exceptionClassName}'";
     }
     return "{$date} {$level}{$appName} {$name} {$type}{$success} {$localSocket} {$username}{$remoteAddr}\\[ID:{$sessionID}\\] {$msg}";
 }
 /**
  * Adds a security event.  These events are used to check that the user has
  * not reached the security thresholds set in the properties file.  If a PHP
  * session has been started the events are stored there, otherwise they are
  * merely stored as an instance property.  This means that if a session has
  * not been started prior to calling this function then events will not be
  * tracked across requests.
  *
  * @param string $eventName The name of the event that occurred.
  *
  * @return null
  */
 private function _addSecurityEvent($eventName)
 {
     // if there is a threshold, then track this event
     $threshold = ESAPI::getSecurityConfiguration()->getQuota($eventName);
     if ($threshold === null) {
         return;
     }
     // determine the storage for events
     if (isset($_SESSION)) {
         if (!array_key_exists('ESAPI', $_SESSION)) {
             $_SESSION['ESAPI'] = array();
         }
         if (!array_key_exists('IntrusionDetector', $_SESSION['ESAPI'])) {
             $_SESSION['ESAPI']['IntrusionDetector'] = array();
         }
         if (!array_key_exists('UserEvents', $_SESSION['ESAPI']['IntrusionDetector'])) {
             $_SESSION['ESAPI']['IntrusionDetector']['UserEvents'] = array();
         }
         // If a session was started after events existed then ensure those
         // events are added to the session store
         if (is_array($this->_userEvents) && $this->_userEvents !== $_SESSION['ESAPI']['IntrusionDetector']['UserEvents']) {
             $_SESSION['ESAPI']['IntrusionDetector']['UserEvents'] = $this->_userEvents;
         }
         // Assign a reference to the session store
         $this->_userEvents =& $_SESSION['ESAPI']['IntrusionDetector']['UserEvents'];
     } else {
         if (!isset($this->_userEvents)) {
             $this->_userEvents = array();
         }
     }
     $event = null;
     if (array_key_exists($eventName, $this->_userEvents)) {
         $event = $this->_userEvents[$eventName];
     }
     if ($event == null) {
         $this->_userEvents[$eventName] = new Event($eventName);
         $event = $this->_userEvents[$eventName];
     }
     if ($threshold->count > 0) {
         $event->increment($threshold->count, $threshold->interval);
     }
 }
 /**
  * Add a hash to a User's hashed password list.  This method is used to store a user's old password hashes
  * to be sure that any new passwords are not too similar to old passwords.
  *
  * @param user
  * 		the user to associate with the new hash
  * @param hash
  * 		the hash to store in the user's password hash list
  */
 private function setHashedPassword($user, $hash)
 {
     $hashes = $this->getAllHashedPasswords($user, true);
     $hashes[0] = $hash;
     if (count($hashes) > ESAPI::getSecurityConfiguration()->getMaxOldPasswordHashes()) {
         //TODO: Verify
         array_pop($hashes);
     }
     $this->logger->info(ESAPILogger::SECURITY, TRUE, "New hashed password stored for " . $user->getAccountName());
 }
Esempio n. 10
0
 /**
  * Executor constructor.
  *
  * @return does not return a value.
  */
 public function __construct()
 {
     $this->_auditor = ESAPI::getAuditor('Executor');
     $this->_config = ESAPI::getSecurityConfiguration();
 }
Esempio n. 11
0
 public function __construct($accountName)
 {
     $this->setAccountName($accountName);
     //TODO: Not the best way IMHO. I'd rather call the method via factory object each time. Needs discussion..
     $this->IDLE_TIMEOUT_LENGTH = ESAPI::getSecurityConfiguration()->getSessionIdleTimeoutLength();
     $this->ABSOLUTE_TIMEOUT_LENGTH = ESAPI::getSecurityConfiguration()->getSessionAbsoluteTimeoutLength();
     do {
         $id = ESAPI::getRandomizer()->getRandomLong();
         if (ESAPI::getAuthenticator()->getUserById($id) == null && $id != 0) {
             $this->setAccountID($id);
         }
     } while ($this->getAccountID() == 0);
 }
Esempio n. 12
0
/**
 * Helper returns the ESAPILogger log file absolute path.
 *
 * @return string|bool RealPath for the ESAPI Auditor log file or
 *                     false.
 */
function getLogFileLoc()
{
    $filename = ESAPI::getSecurityConfiguration()->getLogFileName();
    return realpath($filename);
}
 /**
  * Test constructor of class SafeFile with Invalid path.
  *
  * @return bool True on Pass.
  */
 function testSafeFileLowByteInFileName()
 {
     $config = ESAPI::getSecurityConfiguration();
     $file = $config->getResourceDirectory() . "/ESAPI" . chr(8) . ".xml";
     $this->setExpectedException('EnterpriseSecurityException');
     $sf = new SafeFile($file);
 }
 /**
  * This test will trigger IDS at a point which demonstrates the calculation
  * of event intervals.  Using a threshold that triggers after 5 events
  * within 5 seconds, four events will occur at 1 second intervals, then a
  * pause of 3 seconds and then 3 more events in quick succession.  IDS
  * should not trigger until the 7th event.
  *
  *                                   *
  *         e   e   e   e           eee
  *         |-+-|-+-|-+-|-+-|-+-|-+-|-+-|-+-|
  *         0   1   2   3   4   5   6   7   8
  *                 |___________________|
  *                   5 second interval
  *
  * @return bool True on Pass.
  */
 public function testSlidingInterval()
 {
     if ($this->_logFileLoc === false) {
         $this->fail('Cannot perform this test because the log file cannot be found.');
     }
     $eventName = 'SlidingIntervalTestEvent';
     $threshold = ESAPI::getSecurityConfiguration()->getQuota($eventName);
     $date = new DateTime();
     $find = "User exceeded quota of {$threshold->count} " . "per {$threshold->interval} seconds for event {$eventName}." . sprintf(' Taking the following %d action%s - ', count($threshold->actions), count($threshold->actions) > 1 ? 's' : '') . implode(', ', $threshold->actions) . '.';
     $m = 'Test attempts to detect IntrusionDetector' . ' action log message in logfile - %s';
     // Generate 4 events at 1 sec intervals
     for ($i = 0; $i < 4; $i++) {
         ESAPI::getIntrusionDetector()->addEvent($eventName, 'This is a Test Event for IntrusionDetectorTest.');
         usleep(1000000);
     }
     // Sleep for a further 2 secs (for a total of 3 secs between this and
     // the next event.
     usleep(2000000);
     // The following two events should not trigger...
     ESAPI::getIntrusionDetector()->addEvent($eventName, 'This is a Test Event for IntrusionDetectorTest.');
     $this->assertFalse(fileContainsExpected($this->_logFileLoc, $find, $date, 10, $this->_logDateFormat), $m);
     ESAPI::getIntrusionDetector()->addEvent($eventName, 'This is a Test Event for IntrusionDetectorTest.');
     $this->assertFalse(fileContainsExpected($this->_logFileLoc, $find, $date, 10, $this->_logDateFormat), $m);
     // OK this event SHOULD trigger!
     ESAPI::getIntrusionDetector()->addEvent($eventName, 'This is a Test Event for IntrusionDetectorTest.');
     $this->assertTrue(fileContainsExpected($this->_logFileLoc, $find, $date, 10, $this->_logDateFormat), $m);
 }
 /**
  * Test supplying constructor with an instance of a validator
  */
 function testCCVR_constructValidator()
 {
     $config = ESAPI::getSecurityConfiguration();
     $pattern = $config->getValidationPattern('CreditCard');
     $ccr = new StringValidationRule('CreditCardValidator', null, $pattern);
     $ccr->setMaximumLength(16);
     // 19 in the default validator
     $ccvr = new CreditCardValidationRule('CreditCardValidatorLuhn', null, $ccr);
     $this->assertTrue($ccvr->isValid('testCCVR_constructValidator', '0000000000000000'));
     $this->assertFalse($ccvr->isValid('testCCVR_constructValidator', '0000-0000-0000-0000'));
 }