def create_test_user(self, username=None, password=None): """ Creates a test user. @return: the test user @raises AuthenticationException: """ if username is None: username = ESAPI.randomizer().get_random_string(8, DefaultEncoder.CHAR_ALPHANUMERICS) if password is None: password = ESAPI.randomizer().get_random_string(8, DefaultEncoder.CHAR_ALPHANUMERICS) while True: try: ESAPI.authenticator().verify_password_strength(password) except: password = ESAPI.randomizer().get_random_string(8, DefaultEncoder.CHAR_ALPHANUMERICS) else: break caller = inspect.stack()[2][3] print (_("Creating user %(username)s for %(caller)s") % {'username' : username, 'caller' : caller}) # Not sure if User tests should be coupled with Authenticator... user = ESAPI.authenticator().create_user(username, password, password) return user
def test_decode_from_base64(self): instance = ESAPI.encoder() for i in range(100): random_string = ESAPI.randomizer().get_random_string( 20, Encoder.CHAR_SPECIALS ) encoded = instance.encode_for_base64( random_string ) decoded = instance.decode_from_base64( encoded ) self.assertEqual( random_string, decoded ) for i in range(100): random_string = ESAPI.randomizer().get_random_string( 20, Encoder.CHAR_SPECIALS ) encoded = ESAPI.randomizer().get_random_string(1, Encoder.CHAR_ALPHANUMERICS) + instance.encode_for_base64( random_string ) decoded = instance.decode_from_base64( encoded ) self.assertFalse( random_string == decoded )
def log(self, level, event_type, message, exception=None): """ Log the message after optionally encoding any special characters that might be dangerous when viewed by an HTML based log viewer. Also encode any carriage returns and line feeds to prevent log injection attacks. This logs all the supplied parameters plus the user ID, user's source IP, a logging specific session ID, and the current date/time. It will only log the message if the current logging level is enabled, otherwise it will discard the message. @param level: the severity level of the security event @param event_type: the event_type of the event (SECURITY, FUNCTIONALITY, etc.) @param message: the message @param exception: an exception """ # Before we waste all kinds of time preparing this event for the # log, let check to see if its loggable if not self.pyLogger.isEnabledFor(level): return user = ESAPI.authenticator().current_user # create a random session number for the user to represent the # user's 'session', if it doesn't exist already sid = _("unknown") request = ESAPI.http_utilities().current_request if request is not None: session = request.session if session is not None: sid = session.get('ESAPI_SESSION', None) # if there is no session id for the user yet, create one # and store it in the user's session if sid is None: sid = str(ESAPI.randomizer().get_random_integer(0, 1000000)) session['ESAPI_SESSION'] = sid # ensure there's something to log if message is None: message = "" # ensure no CRLF injection into logs for forging records clean = message.replace('\n', '_').replace('\r', '_') if ESAPI.security_configuration().get_log_encoding_required(): clean = ESAPI.encoder().encode_for_html(message) if message != clean: clean += " (Encoded)" extra = { 'eventType' : str(event_type), 'eventSuccess' : [_("SUCCESS"),_("FAILURE")][event_type.is_success()], 'user' : user.account_name, 'hostname' : user.last_host_address, 'sessionID' : sid, } self.pyLogger.log(level, clean, extra=extra)
def get_unique_random_reference(self, invalid=None): candidate = None if invalid is None: invalid = () while candidate is None or self.itod.has_key(candidate) or candidate in invalid: candidate = ESAPI.randomizer().get_random_string(self.INDIRECT_LENGTH, Encoder.CHAR_ALPHANUMERICS) return candidate
def test_get_random_string(self): length = 20 instance = ESAPI.randomizer() for i in range (100): result = instance.get_random_string(length, Encoder.CHAR_ALPHANUMERICS) for char in result: if char not in Encoder.CHAR_ALPHANUMERICS: self.fail() self.assertEquals(length, len(result))
def test_encode_for_base64(self): instance = ESAPI.encoder() self.assertEquals(None, instance.encode_for_base64(None)) self.assertEquals(None, instance.decode_from_base64(None)) for i in range(100): random_string = ESAPI.randomizer().get_random_string( 20, Encoder.CHAR_SPECIALS ) encoded = instance.encode_for_base64( random_string ) decoded = instance.decode_from_base64( encoded ) self.assertEquals( random_string, decoded )
def test_get_random_string(self): length = 20 instance = ESAPI.randomizer() for i in range(100): result = instance.get_random_string(length, Encoder.CHAR_ALPHANUMERICS) for char in result: if char not in Encoder.CHAR_ALPHANUMERICS: self.fail() self.assertEquals(length, len(result))
def get_unique_random_reference(self, invalid=None): candidate = None if invalid is None: invalid = () while (candidate is None or self.itod.has_key(candidate) or candidate in invalid): candidate = ESAPI.randomizer().get_random_string( self.INDIRECT_LENGTH, Encoder.CHAR_ALPHANUMERICS) return candidate
def test_get_random_guid(self): instance = ESAPI.randomizer() guids = [] for i in range(100): guid = instance.get_random_guid() #print guid self.assertEquals(36, len(guid)) # Check length self.assertEquals('4', guid[14]) # Check version 4 assert guid[19] in '89ab' # Check high bits if guid in guids: self.fail() guids.append(guid)
def test_get_random_guid(self): instance = ESAPI.randomizer() guids = [] for i in range(100): guid = instance.get_random_guid() #print guid self.assertEquals(36, len(guid)) # Check length self.assertEquals('4', guid[14]) # Check version 4 assert guid[19] in '89ab' # Check high bits if guid in guids: self.fail() guids.append(guid)
def test_get_random_boolean(self): instance = ESAPI.randomizer() trues = 0 falses = 0 for i in range(1000): ans = instance.get_random_boolean() if ans: trues += 1 else: falses += 1 if trues > 700 or falses > 700: print "There may be a problem with the randomizer." print "Got %s trues and %s falses" % (trues, falses) self.fail()
def test_get_random_float(self): min_ = -20.5234 max_ = 100.12124 instance = ESAPI.randomizer() min_result = max_result = (max_ - min_) / 2 for i in range(100): result = instance.get_random_float(min_, max_) #print result if result < min_result: min_result = result if result > max_result: max_result = result assert min_result >= min_ and max_result <= max_
def test_crypt(self): instance = ESAPI.encryptor() def check(plaintext): ciphertext = instance.encrypt(plaintext) result = instance.decrypt(ciphertext) self.assertEquals(plaintext, result) # Example plaintext check("test1234") # 20 random strings for i in range(20): check(ESAPI.randomizer().get_random_string(40, Encoder.CHAR_ALPHANUMERICS))
def test_get_random_float(self): min_ = -20.5234 max_ = 100.12124 instance = ESAPI.randomizer() min_result = max_result = ( max_ - min_ ) / 2 for i in range(100): result = instance.get_random_float(min_, max_) #print result if result < min_result: min_result = result if result > max_result: max_result = result assert min_result >= min_ and max_result <= max_
def test_get_random_boolean(self): instance = ESAPI.randomizer() trues = 0 falses = 0 for i in range(1000): ans = instance.get_random_boolean() if ans: trues += 1 else: falses += 1 if trues > 700 or falses > 700: print "There may be a problem with the randomizer." print "Got %s trues and %s falses" % (trues, falses) self.fail()
def test_sign_and_verify(self): instance = ESAPI.encryptor() def check(plaintext): sig = instance.sign(plaintext) self.assertTrue( instance.verify_signature(sig, plaintext) ) self.assertFalse( instance.verify_signature(sig, "ridiculous") ) self.assertFalse( instance.verify_signature("ridiculous", plaintext) ) # Example plaintext check("test1234") # 20 random strings for i in range(20): check(ESAPI.randomizer().get_random_string(40, Encoder.CHAR_ALPHANUMERICS))
def test_crypt(self): instance = ESAPI.encryptor() def check(plaintext): ciphertext = instance.encrypt(plaintext) result = instance.decrypt(ciphertext) self.assertEquals(plaintext, result) # Example plaintext check("test1234") # 20 random strings for i in range(20): check(ESAPI.randomizer().get_random_string( 40, Encoder.CHAR_ALPHANUMERICS))
def test_sign_and_verify(self): instance = ESAPI.encryptor() def check(plaintext): sig = instance.sign(plaintext) self.assertTrue(instance.verify_signature(sig, plaintext)) self.assertFalse(instance.verify_signature(sig, "ridiculous")) self.assertFalse(instance.verify_signature("ridiculous", plaintext)) # Example plaintext check("test1234") # 20 random strings for i in range(20): check(ESAPI.randomizer().get_random_string( 40, Encoder.CHAR_ALPHANUMERICS))
def seal(self, data, expiration): try: if isinstance(expiration, datetime): expiration_seconds = time.mktime(expiration.timetuple()) elif isinstance(expiration, timedelta): obj = datetime.now() + expiration expiration_seconds = time.mktime(obj.timetuple()) else: expiration_seconds = expiration # Mix in some random data so even identical data and timestamp # produce different seals random = ESAPI.randomizer().get_random_string( 10, Encoder.CHAR_ALPHANUMERICS) plaintext = str(expiration_seconds) + ":" + random + ":" + data # add integrity check sig = self.sign(plaintext) ciphertext = self.encrypt(plaintext + ":" + sig) return ciphertext except EncryptionException, err: raise IntegrityException(err.user_message, err.log_message, err)
def __init__(self, account_name): """ Instantiates a new user. @param account_name: The name of this user's account. """ User.__init__(self) self._account_name = None self._set_account_name(account_name) # Get random numbers until we find an unused account number # WARNING: This could cause in infinite loop if the number of users equals the keyspace of uids. while True: id = ESAPI.randomizer().get_random_integer(1) if id != 0 and not ESAPI.authenticator().exists(account_id=id): self._account_id = id break self.logger = ESAPI.logger("DefaultUser") self._screen_name = None self._csrf_token = self.reset_csrf_token() self._roles = [] self._locked = False self._logged_in = False self._enabled = False self._last_host_address = None self._last_password_change_time = None self._last_login_time = datetime.min self._last_failed_login_time = datetime.min self._expiration_time = datetime.max self._sessions = [] # Security event dictionary, used by the IntrusionDetector self.event_map = {} self._failed_login_count = 0 self._locale = None
def __init__(self, account_name): """ Instantiates a new user. @param account_name: The name of this user's account. """ User.__init__(self) self._account_name = None self._set_account_name(account_name) # Get random numbers until we find an unused account number # WARNING: This could cause in infinite loop if the number of users equals the keyspace of uids. while True: id = ESAPI.randomizer().get_random_integer(1) if id != 0 and not ESAPI.authenticator().exists(account_id=id): self._account_id = id break self.logger = ESAPI.logger("DefaultUser") self._screen_name = None self._csrf_token = self.reset_csrf_token() self._roles = [] self._locked = False self._logged_in = False self._enabled = False self._last_host_address = None self._last_password_change_time = None self._last_login_time = datetime.min self._last_failed_login_time = datetime.min self._expiration_time = datetime.max self._sessions = [] # Security event dictionary, used by the IntrusionDetector self.event_map = {} self._failed_login_count = 0 self._locale = None
def seal(self, data, expiration): try: if isinstance(expiration, datetime): expiration_seconds = time.mktime(expiration.timetuple()) elif isinstance(expiration, timedelta): obj = datetime.now() + expiration expiration_seconds = time.mktime(obj.timetuple()) else: expiration_seconds = expiration # Mix in some random data so even identical data and timestamp # produce different seals random = ESAPI.randomizer().get_random_string( 10, Encoder.CHAR_ALPHANUMERICS ) plaintext = str(expiration_seconds) + ":" + random + ":" + data # add integrity check sig = self.sign(plaintext) ciphertext = self.encrypt(plaintext + ":" + sig) return ciphertext except EncryptionException, err: raise IntegrityException( err.user_message, err.log_message, err )
def reset_csrf_token(self): self._csrf_token = ESAPI.randomizer().get_random_string( 8, Encoder.CHAR_ALPHANUMERICS) return self.csrf_token
def log(self, level, event_type, message, exception=None): """ Log the message after optionally encoding any special characters that might be dangerous when viewed by an HTML based log viewer. Also encode any carriage returns and line feeds to prevent log injection attacks. This logs all the supplied parameters plus the user ID, user's source IP, a logging specific session ID, and the current date/time. It will only log the message if the current logging level is enabled, otherwise it will discard the message. @param level: the severity level of the security event @param event_type: the event_type of the event (SECURITY, FUNCTIONALITY, etc.) @param message: the message @param exception: an exception """ # Before we waste all kinds of time preparing this event for the # log, let check to see if its loggable if not self.pyLogger.isEnabledFor(level): return user = ESAPI.authenticator().current_user # create a random session number for the user to represent the # user's 'session', if it doesn't exist already sid = _("unknown") request = ESAPI.http_utilities().current_request if request is not None: session = request.session if session is not None: sid = session.get('ESAPI_SESSION', None) # if there is no session id for the user yet, create one # and store it in the user's session if sid is None: sid = str(ESAPI.randomizer().get_random_integer( 0, 1000000)) session['ESAPI_SESSION'] = sid # ensure there's something to log if message is None: message = "" # ensure no CRLF injection into logs for forging records clean = message.replace('\n', '_').replace('\r', '_') if ESAPI.security_configuration().get_log_encoding_required(): clean = ESAPI.encoder().encode_for_html(message) if message != clean: clean += " (Encoded)" extra = { 'eventType': str(event_type), 'eventSuccess': [_("SUCCESS"), _("FAILURE")][event_type.is_success()], 'user': user.account_name, 'hostname': user.last_host_address, 'sessionID': sid, } self.pyLogger.log(level, clean, extra=extra)
def reset_csrf_token(self): self._csrf_token = ESAPI.randomizer().get_random_string(8, Encoder.CHAR_ALPHANUMERICS) return self.csrf_token
def test_get_random_filename(self): instance = ESAPI.randomizer() for i in range(10): instance.get_random_filename('txt')
def test_get_random_filename(self): instance = ESAPI.randomizer() for i in range(10): instance.get_random_filename('txt')