def load_configuration(self):
        """Load configuration"""

        # Get the correct set of modules
        global conf, resources, settings
        try:
            # If esapi.test.conf was already imported, we know we are running a unit
            # test, so we should load the testing configuration

            if 'esapi.test.conf' in sys.modules:
                self.log_special(
                    _("WARNING - LOADING UNIT TEST CONFIGURATION! IF YOU ARE NOT RUNNING UNIT TESTS, SOMETHING IS VERY WRONG AND YOUR APP IS NOT SECURE!"
                      ))
                import esapi.test.conf as conf
                import esapi.test.conf.resources as resources
                import esapi.test.conf.settings as settings
            else:
                import esapi.conf as conf
                import esapi.conf.resources as resources
                import esapi.conf.settings as settings

        except ImportError:
            raise ImportError, _(
                "Unable to import settings file - Check settings.py")

        self.log_special(_("Loaded ESAPI properties"))

        self.log_special(_(" ======Master Configuration======"))

        for option in dir(settings):
            if "Master" not in option and option[0] != "_":
                self.log_special("  |   %(key)s = %(value)s" % {
                    "key": option,
                    "value": str(settings.__dict__[option])
                })
    def add_event(self, event_name, log_message):
        self.logger.warning(
            Logger.SECURITY_FAILURE,
            _("Security event %(name)s received: %(message)s") % {
                'name': event_name,
                'message': log_message,
            })

        # Add the event to the current user, which may trigger a detector
        user = ESAPI.authenticator().current_user

        try:
            self.add_security_event(user, "event_" + event_name)
        except IntrusionException, extra:
            quota = ESAPI.security_configuration().get_quota("event_" +
                                                             event_name)
            for action in quota.actions:
                message = (_(
                    "User exceeded quota of %(count)s per %(interval)s seconds for event %(event_name)s. Taking actions %(actions)s"
                ) % {
                    'count': quota.count,
                    'interval': quota.interval,
                    'event_name': event_name,
                    'actions': quota.actions,
                })
                self.take_security_action(action, message)
 def assert_authorized_for_url(self, url):
     if len(self.url_map) == 0:
         self.url_map = self.load_rules(self.URLACFILE)
     if not self.match_rule(self.url_map, url):
         raise AccessControlException(
             _("Not authorized for URL"),
             _("Not authorized for URL: %(url)s") % {'url': url})
 def assert_authorized_for_file(self, filepath):
     if len(self.file_map) == 0:
         self.file_map = self.load_rules(self.FILEACFILE)
     if not self.match_rule(self.file_map, filepath.replace("\\\\", "/")):
         raise AccessControlException(
             _("Not authorized for file"),
             _("Not authorized for file: %(file)s") % {'file': filepath})
Ejemplo n.º 5
0
 def hash(self, plaintext, salt, iterations=None):
     # Verify a MasterSalt has been set
     if not self.master_salt or len(self.master_salt) < 20:
         raise Exception(
             _("There is an error in the application configuration. The MasterSalt has not been set properly. Please see the instructions in the README for setting up a crypto keyring. Currently, Encryptor_MasterSalt=%(value)s") % 
             {'value' : self.master_salt})
 
     if iterations is None: 
         iterations = self.hash_iterations
 
     try:
         digest = hashlib.new(self.hash_algorithm)
         digest.update(self.master_salt)
         digest.update(salt)
         digest.update(plaintext)
         
         bytes = digest.digest()
         for i in range(self.hash_iterations):
             digest = hashlib.new(self.hash_algorithm)
             digest.update(bytes)
             bytes = digest.digest()
             
         encoded = ESAPI.encoder().encode_for_base64(bytes)
         return encoded
         
     except ValueError, e:
         raise EncryptionException(
             _("Problem hashing"),
             _("Internal Error - Can't find hash algorithm ") + self.hash_algorithm  
             )
    def validate_roles(self, roles):
        """
        Checks that the roles passed in contain only letters, numbers, and
        underscores. Also checks that roles are no more than 10 characters long.
        If a role does not pass validation, it is not included in the list of
        roles returned by this method. A log warning is also generated for any
        invalid roles.
        
        @param roles: the list of roles to validate according to the criteria
            stated above.
        @return: a list of roles that are valid according to the criteria
            stated above.
        """
        ret = []
        for role in roles:
            canonical = ''
            try:
                stripped = role.strip()
                canonical = ESAPI.encoder().canonicalize(stripped)
            except EncodingException, extra:
                self.logger.warning(
                    Logger.SECURITY_FAILURE,
                    _("Failed to canonicalize role: %(role)s") %
                    {'role': stripped}, extra)

            if not ESAPI.validator().is_valid_input(
                    "Roles in FileBasedAccessController", canonical,
                    "AccessControlRule", 200, False):
                self.logger.warning(
                    Logger.SECURITY_FAILURE,
                    _("Role is invalid, and was not added to the list of roles for this rule: %(role)s"
                      ) % {'role': stripped})
            else:
                ret.append(stripped)
Ejemplo n.º 7
0
 def __init__(self):
     Encryptor.__init__(self)
     self.logger = ESAPI.logger("DefaultEncryptor")
     
     # Hashing
     self.hash_algorithm = ESAPI.security_configuration().get_hash_algorithm()
     self.hash_iterations = ESAPI.security_configuration().get_hash_iterations()
     
     # Encryption
     self.encrypt_algorithm = ESAPI.security_configuration().get_encryption_algorithm()
     if self.encrypt_algorithm not in self.VALID_ENCRYPTION_ALGOS:
         raise EncryptionException(
             _("Encryption Failure - Unknown algorithm for encryption: %(algorithm)s") %
             {'algorithm' : self.encrypt_algorithm} )
     
     self.encryption_key_length = ESAPI.security_configuration().get_encryption_key_length()
     self.master_salt = ESAPI.security_configuration().get_master_salt()
     
     # Public key crypto
     self.signing_algorithm = ESAPI.security_configuration().get_digital_signature_algorithm()
     if self.signing_algorithm not in self.VALID_SIGNING_ALGOS:
         raise EncryptionException(
             _("Failure to encrypt"),
             _("Encryption Failure - Unknown algorithm for signing: %(algorithm)s") %
             {'algorithm' : self.signing_algorithm} )
     self.signing_key_length = ESAPI.security_configuration().get_digital_signature_key_length()
     
     # Key locations
     self.keys_location = os.path.realpath(ESAPI.security_configuration().get_encryption_keys_location()) + '/'
     self.keys_symmetric_location = self.keys_location + "symmetric"
     self.keys_asymmetric_private_location = self.keys_location + "asymmetric-private"
     self.keys_asymmetric_public_location = self.keys_location + "asymmetric-public"
Ejemplo n.º 8
0
 def test_change_password(self):
     instance = ESAPI.authenticator()
     old_password = '******'
     user = self.create_test_user(password=old_password)
     print (_("Hash of %(old_password)s = %(hash)s") %
         {'old_password' : old_password,
          'hash' : instance.get_hashed_password(user)})
     
     password1 = "SomethingElse34#$"
     user.change_password(old_password, password1, password1)
     print (_("Hash of %(password)s = %(hash)s") %
         {'password' : password1,
          'hash' : instance.get_hashed_password(user)})
     self.assertTrue(user.verify_password(password1))
     self.assertFalse(user.verify_password(old_password))
     
     password2 = "YetAnother56%^"
     user.change_password(password1, password2, password2)
     print (_("Hash of %(password)s = %(hash)s") %
         {'password' : password2,
          'hash' : instance.get_hashed_password(user)})
     self.assertTrue(user.verify_password(password2))
     self.assertFalse(user.verify_password(password1))
     
     try: 
         user.change_password(password2, password1, password1)
         # Should not be able to re-use a password
         self.fail()
     except AuthenticationException:
         pass
         
     self.assertFalse(user.verify_password("badpass"))
    def get_direct_reference(self, indirect):
        if self.itod.has_key(indirect):
            return self.itod[indirect]

        raise AccessControlException(
            _("Access denied"), _("Request for invalid indirect reference: %(ref)s") % {"ref": indirect}
        )
     
 def validate_roles(self, roles):
     """
     Checks that the roles passed in contain only letters, numbers, and
     underscores. Also checks that roles are no more than 10 characters long.
     If a role does not pass validation, it is not included in the list of
     roles returned by this method. A log warning is also generated for any
     invalid roles.
     
     @param roles: the list of roles to validate according to the criteria
         stated above.
     @return: a list of roles that are valid according to the criteria
         stated above.
     """
     ret = []
     for role in roles:
         canonical = ''
         try:
             stripped = role.strip()
             canonical = ESAPI.encoder().canonicalize(stripped)
         except EncodingException, extra:
             self.logger.warning( Logger.SECURITY_FAILURE,
                 _("Failed to canonicalize role: %(role)s") %
                 {'role' : stripped},
                 extra )
                 
         if not ESAPI.validator().is_valid_input(
             "Roles in FileBasedAccessController",
             canonical,
             "AccessControlRule", 200, False ):
             self.logger.warning( Logger.SECURITY_FAILURE,
                 _("Role is invalid, and was not added to the list of roles for this rule: %(role)s") %
                 {'role' : stripped} )
         else:
Ejemplo n.º 11
0
 def set_remember_token(self, password, max_age, domain, path, request=None, response=None):
     if request is None:
         request = self.current_request
         
     if response is None:
         response = self.current_response
         
     user = ESAPI.authenticator().current_user
     try:
         self.kill_cookie(self.REMEMBER_TOKEN_COOKIE_NAME, request, response)
         # Seal already contains random data
         clear_token = user.account_name + "|" + password
         expiry = datetime.now() + timedelta(seconds=max_age)
         crypt_token = ESAPI.encryptor().seal(clear_token, expiry)
         morsel = Cookie.Morsel()
         morsel.value = crypt_token
         morsel['max-age'] = max_age
         morsel['domain'] = domain
         morsel['path'] = path
         response.cookies[self.REMEMBER_TOKEN_COOKIE_NAME] = morsel
         
         self.logger.info( Logger.SECURITY_SUCCESS,
             _("Enabled remember me token for %(user)s") %
             {'user' : user.account_name} )
         return crypt_token
     except IntegrityException, extra:
         self.logger.warning( Logger.SECURITY_FAILURE,
             _("Attempt to set remember me token failed for %(user)s") %
             {'user' : user.account_name}, extra )
 def assert_authorized_for_data(self, action, key):
     if len(self.data_map) == 0:
         self.data_map = self.load_rules(self.DATAACFILE)
     if not self.match_rule(self.data_map, key, action):
         raise AccessControlException(
             _("Not authorized for data"),
             _("Not authorized for data: %(data)s") % {'data': key})
 def load_configuration(self):
     """Load configuration"""
     
     # Get the correct set of modules
     global conf, resources, settings
     try:
         # If esapi.test.conf was already imported, we know we are running a unit
         # test, so we should load the testing configuration
         
         if 'esapi.test.conf' in sys.modules:
             self.log_special(_("WARNING - LOADING UNIT TEST CONFIGURATION! IF YOU ARE NOT RUNNING UNIT TESTS, SOMETHING IS VERY WRONG AND YOUR APP IS NOT SECURE!"))
             import esapi.test.conf as conf
             import esapi.test.conf.resources as resources
             import esapi.test.conf.settings as settings
         else:
             import esapi.conf as conf
             import esapi.conf.resources as resources
             import esapi.conf.settings as settings
           
     except ImportError:
         raise ImportError, _("Unable to import settings file - Check settings.py")
         
     self.log_special(_("Loaded ESAPI properties"))
     
     self.log_special(_(" ======Master Configuration======"))
     
     for option in dir(settings):
         if "Master" not in option and option[0] != "_":
             self.log_special("  |   %(key)s = %(value)s" % {"key": option, "value": str(settings.__dict__[option])})
Ejemplo n.º 14
0
 def decrypt_hidden_field(self, encrypted):
     try:
         return ESAPI.encryptor().decrypt(encrypted)
     except EncryptionException, extra:
         raise IntrusionException( 
             _("Invalid request"),
             _("Tampering detected. Hidden field data did not decrypt properly."), extra )
    def hash(self, plaintext, salt, iterations=None):
        # Verify a MasterSalt has been set
        if not self.master_salt or len(self.master_salt) < 20:
            raise Exception(
                _("There is an error in the application configuration. The MasterSalt has not been set properly. Please see the instructions in the README for setting up a crypto keyring. Currently, Encryptor_MasterSalt=%(value)s"
                  ) % {'value': self.master_salt})

        if iterations is None:
            iterations = self.hash_iterations

        try:
            digest = hashlib.new(self.hash_algorithm)
            digest.update(self.master_salt)
            digest.update(salt)
            digest.update(plaintext)

            bytes = digest.digest()
            for i in range(self.hash_iterations):
                digest = hashlib.new(self.hash_algorithm)
                digest.update(bytes)
                bytes = digest.digest()

            encoded = ESAPI.encoder().encode_for_base64(bytes)
            return encoded

        except ValueError, e:
            raise EncryptionException(
                _("Problem hashing"),
                _("Internal Error - Can't find hash algorithm ") +
                self.hash_algorithm)
Ejemplo n.º 16
0
    def add_role(self, role):
        """
        If role is a string, it will be lower()'d.
        """
        if isinstance(role, str):
            role = role.lower()

        if ESAPI.validator().is_valid_input("addRole", role, "RoleName",
                                            DefaultUser.MAX_ROLE_LENGTH,
                                            False):
            if role not in self._roles:
                self._roles.append(role)
                self.logger.info(
                    Logger.SECURITY_SUCCESS,
                    _("Role %(role_name)s added to %(account_name)s") % {
                        'role_name': role,
                        'account_name': self.account_name
                    })
            else:
                # Role already assigned
                pass
        else:
            raise AuthenticationAccountsException(
                _("Add role failed"),
                _("Attempt to add invalid role %(role_name)s to %(account_name)s"
                  ) % {
                      'role_name': role,
                      'account_name': self.account_name
                  })
 def assert_authorized_for_function(self, function_name):
     if len(self.function_map) == 0:
         self.function_map = self.load_rules(self.FUNCTIONACFILE)
     if not self.match_rule(self.function_map, function_name):
         raise AccessControlException(
             _("Not authorized for function"), 
             _("Not authorized for function: %(function)s") %
Ejemplo n.º 18
0
 def add_role(self, role):
     """
     If role is a string, it will be lower()'d.
     """
     if isinstance(role, str):
         role = role.lower()
         
     if ESAPI.validator().is_valid_input("addRole",
                         role, 
                         "RoleName", 
                         DefaultUser.MAX_ROLE_LENGTH, 
                         False):
         if role not in self._roles:
             self._roles.append(role)
             self.logger.info(Logger.SECURITY_SUCCESS,
                  _("Role %(role_name)s added to %(account_name)s") %
                  {'role_name' : role,
                   'account_name' : self.account_name})
         else:
             # Role already assigned
             pass
     else:
         raise AuthenticationAccountsException( _("Add role failed"),
             _("Attempt to add invalid role %(role_name)s to %(account_name)s") %
             {'role_name' : role,
              'account_name' : self.account_name})
Ejemplo n.º 19
0
 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) 
Ejemplo n.º 20
0
    def get_direct_reference(self, indirect):
        if self.itod.has_key(indirect):
            return self.itod[indirect]

        raise AccessControlException(
            _("Access denied"),
            _("Request for invalid indirect reference: %(ref)s") %
            {'ref': indirect})
     
 def assert_authorized_for_file(self, filepath):
     if len(self.file_map) == 0:
         self.file_map = self.load_rules(self.FILEACFILE)
     if not self.match_rule(self.file_map, filepath.replace("\\\\","/")):
         raise AccessControlException(
             _("Not authorized for file"), 
             _("Not authorized for file: %(file)s") %
 
 def assert_authorized_for_service(self, service_name):
     if len(self.service_map) == 0:
         self.service_map = self.load_rules(self.SERVICEACFILE)
     if not self.match_rule(self.service_map, service_name):
         raise AccessControlException(
             _("Not authorized for service"), 
             _("Not authorized for service: %(service)s") %
 def assert_authorized_for_service(self, service_name):
     if len(self.service_map) == 0:
         self.service_map = self.load_rules(self.SERVICEACFILE)
     if not self.match_rule(self.service_map, service_name):
         raise AccessControlException(
             _("Not authorized for service"),
             _("Not authorized for service: %(service)s") %
             {'service': service_name})
     
 def assert_authorized_for_data(self, action, key):
     if len(self.data_map) == 0:
         self.data_map = self.load_rules(self.DATAACFILE)
     if not self.match_rule(self.data_map, key, action):
         raise AccessControlException(
             _("Not authorized for data"), 
             _("Not authorized for data: %(data)s") %
 def assert_authorized_for_url(self, url):
     if len(self.url_map) == 0:
         self.url_map = self.load_rules(self.URLACFILE)
     if not self.match_rule(self.url_map, url):
         raise AccessControlException(
             _("Not authorized for URL"), 
             _("Not authorized for URL: %(url)s") %
              { 'url' : url } )
Ejemplo n.º 26
0
 def decrypt_hidden_field(self, encrypted):
     try:
         return ESAPI.encryptor().decrypt(encrypted)
     except EncryptionException, extra:
         raise IntrusionException(
             _("Invalid request"),
             _("Tampering detected. Hidden field data did not decrypt properly."
               ), extra)
 def sign(self, data):
     try:
         signer = keyczar.Signer.Read(self.keys_asymmetric_private_location)
         signature = signer.Sign(data)
         return signature
     except KeyczarError, err:
         raise EncryptionException(_("Problem signing"),
                                   _("Keyczar raised an error"), err)
 def assert_authorized_for_function(self, function_name):
     if len(self.function_map) == 0:
         self.function_map = self.load_rules(self.FUNCTIONACFILE)
     if not self.match_rule(self.function_map, function_name):
         raise AccessControlException(
             _("Not authorized for function"),
             _("Not authorized for function: %(function)s") %
             {'function': function_name})
 def decrypt(self, ciphertext):
     try:
         crypter = keyczar.Crypter.Read(self.keys_symmetric_location)
         plaintext = crypter.Decrypt(ciphertext)
         return plaintext
     except KeyczarError, err:
         raise EncryptionException(_("Problem decrypting"),
                                   _("Keyczar raised an error"), err)
Ejemplo n.º 30
0
 def _set_last_host_address(self, address):
     if (self._last_host_address is not None and 
         self._last_host_address != address):
         raise AuthenticationHostException( _("Host change"),
             _("User sessions just jumped from %(old)s to %(new)s") %
             {'old' : self._last_host_address,
              'new' : address})
     self._last_host_address = address
Ejemplo n.º 31
0
 def decrypt(self, ciphertext):
     try:
         crypter = keyczar.Crypter.Read(self.keys_symmetric_location)
         plaintext = crypter.Decrypt(ciphertext)
         return plaintext
     except KeyczarError, err:
         raise EncryptionException(
             _("Problem decrypting"),
             _("Keyczar raised an error"),
             err )
Ejemplo n.º 32
0
 def sign(self, data):
     try:
         signer = keyczar.Signer.Read(self.keys_asymmetric_private_location)
         signature = signer.Sign(data)
         return signature
     except KeyczarError, err:
         raise EncryptionException(
             _("Problem signing"),
             _("Keyczar raised an error"),
             err )
Ejemplo n.º 33
0
 def __setitem__(self, context, validation_exception):
     if context is None:
         raise RuntimeError(_("context parameter cannot be None"))
     if validation_exception is None:
         raise RuntimeError(_("validation_exception parameter cannot be None"))
     if self.has_key(context):
         raise RuntimeError(_("Context %(context)s already exists, must be unique") % 
             {'context' : context})
         
     dict.__setitem__(self, context, validation_exception)
Ejemplo n.º 34
0
 def _set_last_host_address(self, address):
     if (self._last_host_address is not None
             and self._last_host_address != address):
         raise AuthenticationHostException(
             _("Host change"),
             _("User sessions just jumped from %(old)s to %(new)s") % {
                 'old': self._last_host_address,
                 'new': address
             })
     self._last_host_address = address
Ejemplo n.º 35
0
    def __setitem__(self, context, validation_exception):
        if context is None:
            raise RuntimeError(_("context parameter cannot be None"))
        if validation_exception is None:
            raise RuntimeError(
                _("validation_exception parameter cannot be None"))
        if self.has_key(context):
            raise RuntimeError(
                _("Context %(context)s already exists, must be unique") %
                {'context': context})

        dict.__setitem__(self, context, validation_exception)
 def get_class_for_interface(self, interface):
     interface = interface.lower()
     prop = "ESAPI_%s" % (interface,)
     
     try:
         fqn = getattr(settings, prop)
     except AttributeError, extra:
         raise ConfigurationException( 
             _('There is an error in the application configuration. See the security log for more details.'), 
             _("Class for this interface not specified in settings: %(interface)s") % 
             {'interface' : interface},
             extra )
    def get_class_for_interface(self, interface):
        interface = interface.lower()
        prop = "ESAPI_%s" % (interface, )

        try:
            fqn = getattr(settings, prop)
        except AttributeError, extra:
            raise ConfigurationException(
                _('There is an error in the application configuration. See the security log for more details.'
                  ),
                _("Class for this interface not specified in settings: %(interface)s"
                  ) % {'interface': interface}, extra)
 def get_validation_pattern(self, key):
     value = getattr(settings, "Validator_" + key, None)
     if value is None: 
         self.log_special(_("Trying to get validation pattern Validator_%(key)s failed because it doesn't exist") %
         {'key' : key})
         return None
         
     try:
         return re.compile(value)
     except Exception, extra:
         self.log_special(_("SecurityConfiguration for Validator_%(key)s is not a valid regex in settings. Returning None.") % 
             {'key' : key})
         return None
 def increment(self, count, interval):
     now = datetime.now()
     self.times.append(now)
     if len(self.times) > count:
         num_to_remove = len(self.times) - count
         self.times = self.times[num_to_remove:]
         
     if len(self.times) == count:
         first_event_time = self.times[0]
         if now - first_event_time < timedelta(seconds=interval):
             raise IntrusionException(
                 _("Threshold exceeded"),
                 _("Exceeded threshold for %(key)s") %
                 {'key' : self.key} )
Ejemplo n.º 40
0
    def get_valid_filename(self,
                           context,
                           input_,
                           allow_none,
                           error_list=None,
                           allowed_extensions=None):
        try:
            if self.is_empty(input_):
                if allow_none:
                    return None
                raise ValidationException(
                    _("%(context)s: Input file name required") %
                    {'context': context},
                    _("Input required: context=%(context)s, input=%(input)s") %
                    {
                        'context': context,
                        'input': input_
                    }, context)

            # Do basic validation
            self.get_valid_input(context, input_, "Filename", 255, True)

            # Verify extensions
            if not allowed_extensions:
                allowed_extensions = ESAPI.security_configuration(
                ).get_allowed_file_extensions()

            file_ext = os.path.splitext(input_)[1]
            file_ext = file_ext.lower()
            if file_ext in allowed_extensions:
                return input_
            else:
                raise ValidationException(
                    _("%(context)s: Invalid file name does not have valid extension ( %(allowed_extensions)s )"
                      ) % {
                          'context': context,
                          'allowed_extensions': allowed_extensions
                      },
                    _("Invalid file name does not have valid extension ( %(allowed_extensions)s ): context=%(context)s, input=%(input)s"
                      ) % {
                          'allowed_extensions': allowed_extensions,
                          'context': context,
                          'input': input_
                      }, context)

        except ValidationException, extra:
            if error_list is not None:
                error_list[context] = extra
            else:
                raise
        def increment(self, count, interval):
            now = datetime.now()
            self.times.append(now)
            if len(self.times) > count:
                num_to_remove = len(self.times) - count
                self.times = self.times[num_to_remove:]

            if len(self.times) == count:
                first_event_time = self.times[0]
                if now - first_event_time < timedelta(seconds=interval):
                    raise IntrusionException(
                        _("Threshold exceeded"),
                        _("Exceeded threshold for %(key)s") %
                        {'key': self.key})
    def unseal(self, seal):
        try:
            plaintext = self.decrypt(seal)
            parts = plaintext.split(":")
            if len(parts) != 4:
                raise EncryptionException(_("Invalid seal"),
                                          _("Seal was not formatted properly"))

            timestring = parts[0]
            expiration = datetime.fromtimestamp(float(timestring))
            if datetime.now() > expiration:
                raise EncryptionException(_("Invalid seal"),
                                          _("Seal has expired"))
            random, data, sig = parts[1:4]
            sig_data = timestring + ":" + random + ":" + data
            if not self.verify_signature(sig, sig_data):
                raise EncryptionException(_("Invalid seal"),
                                          _("Seal integrity check failed"))

            return data
        except EncryptionException:
            raise
        except Exception, err:
            raise EncryptionException(_("Invalid seal"), _("Invalid seal"),
                                      err)
Ejemplo n.º 43
0
 def unseal(self, seal):
     try:
         plaintext = self.decrypt(seal)
         parts = plaintext.split(":")
         if len(parts) != 4:
             raise EncryptionException(
                 _("Invalid seal"),
                 _("Seal was not formatted properly") )
                 
         timestring = parts[0]
         expiration = datetime.fromtimestamp(float(timestring))
         if datetime.now() > expiration:
             raise EncryptionException(
                 _("Invalid seal"),
                 _("Seal has expired") )
         random, data, sig = parts[1:4]
         sig_data = timestring + ":" + random + ":" + data
         if not self.verify_signature(sig, sig_data):
             raise EncryptionException(
                 _("Invalid seal"),
                 _("Seal integrity check failed") )
                 
         return data
     except EncryptionException:
         raise
     except Exception, err:
         raise EncryptionException(
             _("Invalid seal"),
             _("Invalid seal"),
             err )
Ejemplo n.º 44
0
 def verify_csrf_token(self, request=None):
     if request is None:
         request = self.current_request
         
     user = ESAPI.authenticator().current_user
     
     # check if user authenticated with this request - no CSRF protection required
     if request.headers.has_key(user.csrf_token):
         return
     
     token = request.GET.get(self.CSRF_TOKEN_NAME)
     if user.csrf_token != token:
         raise IntrusionException(
             _("Authentication failed"),
             _("Possibly forged HTTP request without proper CSRF token detected") )
    def get_validation_pattern(self, key):
        value = getattr(settings, "Validator_" + key, None)
        if value is None:
            self.log_special(
                _("Trying to get validation pattern Validator_%(key)s failed because it doesn't exist"
                  ) % {'key': key})
            return None

        try:
            return re.compile(value)
        except Exception, extra:
            self.log_special(
                _("SecurityConfiguration for Validator_%(key)s is not a valid regex in settings. Returning None."
                  ) % {'key': key})
            return None
 def add_exception(self, exception):
     # Log the exception
     if hasattr(exception, 'get_log_message'):
         self.logger.warning( Logger.SECURITY_FAILURE,
             exception.get_log_message(),
             exception )
     else:
         self.logger.warning( Logger.SECURITY_FAILURE,
             exception.message,
             exception )
             
     if isinstance(exception, IntrusionException):
         return
             
     # Add the exception to the current user, which may trigger a
     # dector
     user = ESAPI.authenticator().current_user
     event_name = exception.__class__.__name__
     try:
         self.add_security_event(user, event_name)
     except IntrusionException, extra:
         quota = ESAPI.security_configuration().get_quota(event_name)
         for action in quota.actions:
             message = (_("User exceeded quota of %(count)s per %(interval)s seconds for event %(event_name)s. Taking actions %(actions)s") %
                 {'count' : quota.count,
                  'interval' : quota.interval,
                  'event_name' : event_name,
                  'actions' : quota.actions,})
             self.take_security_action(action, message)
Ejemplo n.º 47
0
 def unlock(self):
     self._locked = False
     self._failed_login_count = 0
     self.logger.info(
         Logger.SECURITY_SUCCESS,
         _("Account unlocked: %(account_name)s") %
         {'account_name': self.account_name})
Ejemplo n.º 48
0
 def assert_secure_request(self, request=None):
     if request is None:
         request = self.current_request
         
     if not request.is_secure():
         raise AccessControlException( _("Insecure request received"),
             _("Receieved non-SSL request: %(url)s") %
             {'url' : request.url})
             
     req_method = "POST"
     if request.method != req_method:
         raise AccessControlException(
             _("Insecure request received"),
             _("Receieved request using %(method)s when only %(req_method)s is allowed") %
             {'method' : request.method,
              'req_method' : req_method} )
Ejemplo n.º 49
0
 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 __init__(self):
     self.logger = ESAPI.logger("Executor")
     self.working_dir = ESAPI.security_configuration().get_working_directory()
     self.max_running_time = ESAPI.security_configuration().get_max_running_time()
     if os.name == "nt":
         self.logger.warning(
             Logger.SECURITY_SUCCESS,
             _("Using WindowsCodec for Executor. If this is not running on Windows, this could allow for injection"),
         )
         self.codec = WindowsCodec()
     else:
         self.logger.warning(
             Logger.SECURITY_SUCCESS,
             _("Using UnixCodec for Executor. If this is not running on Unix, this could allow injection"),
         )
         self.codec = UnixCodec()
Ejemplo n.º 51
0
    def __init__(self, codecs=None):
        """
        Instantiates a new DefaultEncoder.
        
        @param codecs: : a list of codec instances to use for canonicalization
        """
        Encoder.__init__(self)

        self.html_codec = HTMLEntityCodec()
        self.percent_codec = PercentCodec()
        self.javascript_codec = JavascriptCodec()
        self.vbscript_codec = VBScriptCodec()
        self.css_codec = CSSCodec()
        self.ldap_codec = LDAPCodec()
        self.ldap_dn_codec = LDAPDNCodec()

        self.logger = ESAPI.logger("Encoder")

        # Used for canonicalization
        self.codecs = []
        if codecs is None:
            self.codecs.append(self.html_codec)
            self.codecs.append(self.percent_codec)
            self.codecs.append(self.javascript_codec)

            # Leaving out css_codec because it eats / characters
            # Leaving out vbscript_codec because it eats " characters
        else:
            for codec in codecs:
                if not isinstance(codec, Codec):
                    raise TypeError(
                        _("Codecs in list must be instances of children of Codec"
                          ))
                self.codecs.append(codec)
    def add_exception(self, exception):
        # Log the exception
        if hasattr(exception, 'get_log_message'):
            self.logger.warning(Logger.SECURITY_FAILURE,
                                exception.get_log_message(), exception)
        else:
            self.logger.warning(Logger.SECURITY_FAILURE, exception.message,
                                exception)

        if isinstance(exception, IntrusionException):
            return

        # Add the exception to the current user, which may trigger a
        # dector
        user = ESAPI.authenticator().current_user
        event_name = exception.__class__.__name__
        try:
            self.add_security_event(user, event_name)
        except IntrusionException, extra:
            quota = ESAPI.security_configuration().get_quota(event_name)
            for action in quota.actions:
                message = (_(
                    "User exceeded quota of %(count)s per %(interval)s seconds for event %(event_name)s. Taking actions %(actions)s"
                ) % {
                    'count': quota.count,
                    'interval': quota.interval,
                    'event_name': event_name,
                    'actions': quota.actions,
                })
                self.take_security_action(action, message)
Ejemplo n.º 53
0
    def add_cookie(self, response=None, **kwargs):
        if response is None:
            response = self.current_response
            
        if not kwargs.has_key('secure'):
            if ESAPI.security_configuration().get_force_secure_cookies():
                kwargs['secure'] = True
                
        if not kwargs.has_key('httponly'):
            if ESAPI.security_configuration().get_force_http_only_cookies():
                kwargs['httponly'] = True

        # Validate the key and value
        errors = ValidationErrorList()
        safe_key = ESAPI.validator().get_valid_input("cookie name", 
            kwargs['key'], "HTTPCookieName", 50, False, errors)
        safe_value = ESAPI.validator().get_valid_input("cookie value",
            kwargs['value'], "HTTPCookieValue", 5000, False, errors)
            
        kwargs['key'] = safe_key
        kwargs['value'] = safe_value
            
        # If no errors, set the cookie
        if len(errors) == 0:
            response.set_cookie(**kwargs)
            return
        
        # Error!
        self.logger.warning( Logger.SECURITY_FAILURE, 
            _("Attempt to add unsafe data to cookie (skip mode). Skipping cookie and continuing.") )
Ejemplo n.º 54
0
    def verify_csrf_token(self, request=None):
        if request is None:
            request = self.current_request

        user = ESAPI.authenticator().current_user

        # check if user authenticated with this request - no CSRF protection required
        if request.headers.has_key(user.csrf_token):
            return

        token = request.GET.get(self.CSRF_TOKEN_NAME)
        if user.csrf_token != token:
            raise IntrusionException(
                _("Authentication failed"),
                _("Possibly forged HTTP request without proper CSRF token detected"
                  ))
 def add_blacklist_pattern(self, pattern_string):
     try:
         pattern = re.compile(pattern_string)
         self.blacklist_patterns.append(pattern)
     except Exception, extra:
         raise RuntimeError(
             _("Validation misconfiguration, problem with specified pattern: %(pattern)s"
               ) % {'pattern': pattern_string}, extra)
Ejemplo n.º 56
0
    def get_valid(self, context, input_, error_list=None):
        try:
            # check null
            if input_ is None or len(input_) == 0:
                if self.allow_none:
                    return None
                raise ValidationException(
                    _("%(context)s: Input credit card required") %
                    {'context': context},
                    _("Input credit card required: context=%(context)s, input=%(input)s"
                      ) % {
                          'context': context,
                          'input': input_
                      }, context)

            # canonicalize
            canonical = self.ccrule.get_valid(context, input_)

            digits_only = ''.join(
                [char for char in canonical if char.isdigit()])

            # Luhn alogrithm checking
            sum_ = 0
            times_two = False
            for digit in reversed(digits_only):
                digit = int(digit)
                assert 0 <= digit <= 9
                if times_two:
                    digit *= 2
                    if digit > 9:
                        digit -= 9
                sum_ += digit
                times_two = not times_two
            if (sum_ % 10) != 0:
                raise ValidationException(
                    _("%(context)s: Invalid credit card input") %
                    {'context': context},
                    _("Invalid credit card input. Credit card number did not pass Luhn test: context=%(context)s"
                      ) % {'context': context}, context)

            return digits_only
        except ValidationException, extra:
            if error_list is not None:
                error_list[context] = extra
            else:
                raise
Ejemplo n.º 57
0
    def get_header(self, name, request=None):
        if request is None:
            request = self.current_request

        value = request[name]
        return ESAPI.validator().get_valid_input(
            _("HTTP header value: %(value)s") % {'value': value}, value,
            "HTTPHeaderValue", 150, False)
 def get_valid(self, context, input_, error_list=None):
     try:
         # check null
         if input_ is None or len(input_) == 0:
             if self.allow_none:
                 return None
             raise ValidationException( 
                _("%(context)s: Input credit card required") % 
                {'context' : context}, 
                _("Input credit card required: context=%(context)s, input=%(input)s") % 
                {'context' : context,
                 'input' : input_}, 
                context )
                     
         # canonicalize
         canonical = self.ccrule.get_valid(context, input_)
         
         digits_only = ''.join([char for char in canonical if char.isdigit()])
         
         # Luhn alogrithm checking
         sum_ = 0
         times_two = False
         for digit in reversed(digits_only):
             digit = int(digit)
             assert 0 <= digit <= 9
             if times_two:
                 digit *= 2
                 if digit > 9:
                     digit -= 9
             sum_ += digit
             times_two = not times_two
         if (sum_ % 10) != 0:
             raise ValidationException( 
                _("%(context)s: Invalid credit card input") % 
                {'context' : context}, 
                _("Invalid credit card input. Credit card number did not pass Luhn test: context=%(context)s") % 
                {'context' : context}, 
               context )
             
         return digits_only
     except ValidationException, extra:
         if error_list is not None:
             error_list[context] = extra
         else:
             raise