def test_get_user_from_token(self): instance = ESAPI.authenticator() instance.logout() account_name = "testUserFromToken" password = instance.generate_strong_password() user = instance.create_user(account_name, password, password) user.enable() ### request = MockHttpRequest() response = MockHttpResponse() ESAPI.http_utilities().set_current_http(request, response) m = Morsel() m.key = HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME m.value = "ridiculous" request.cookies[m.key] = m # Wrong cookie should fail self.assertRaises(AuthenticationException, instance.login, request, response) user.logout() ### request = MockHttpRequest() response = MockHttpResponse() ESAPI.authenticator().current_user = user new_token = ESAPI.http_utilities().set_remember_token( password, 10000, "test.com", request.path, request, response ) request.set_cookie( key=HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME, value=new_token ) ESAPI.http_utilities().set_current_http(request, response) # Logout the current user so we can log them in with the remember cookie user2 = instance.login(request, response) self.assertEquals(user, user2)
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_get_user(self): instance = ESAPI.authenticator() account_name = "testGetUser" password = "******" instance.create_user(account_name, password, password) self.assertTrue( instance.get_user(account_name) ) self.assertFalse( instance.get_user("ridiculous") )
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 test_hash_password(self): instance = ESAPI.authenticator() username = "******" password = "******" result1 = instance.hash_password(password, username) result2 = instance.hash_password(password, username) self.assertEquals(result1, result2)
def test_create_user(self): instance = ESAPI.authenticator() account_name = "awesomebob" password = "******" user = instance.create_user(account_name, password, password) # duplicate user self.assertRaises(AuthenticationException, instance.create_user, account_name, password, password) # passwords don't match self.assertRaises(AuthenticationException, instance.create_user, "nonmatchuser", "a1b2c3d4e5f6g7h8", "z1b2c3d4e5f6g7h8") # Weak password self.assertRaises(AuthenticationException, instance.create_user, "weakuser", "weak1", "weak1") # None username self.assertRaises(AuthenticationException, instance.create_user, None, "comPl3xPass", "comPl3xPass") # None password self.assertRaises(AuthenticationException, instance.create_user, "nopassword", None, None)
def test_is_authorized_for_service(self): instance = ESAPI.access_controller() auth = ESAPI.authenticator() auth.current_user = auth.get_user("ACAlice") self.assertTrue(instance.is_authorized_for_service("/services/ServiceA")) self.assertFalse(instance.is_authorized_for_service("/services/ServiceB")) self.assertTrue(instance.is_authorized_for_service("/services/ServiceC")) self.assertFalse(instance.is_authorized_for_service("/test/ridiculous")) auth.current_user = auth.get_user("ACBob") self.assertFalse(instance.is_authorized_for_service("/services/ServiceA")) self.assertTrue(instance.is_authorized_for_service("/services/ServiceB")) self.assertFalse(instance.is_authorized_for_service("/services/ServiceF")) self.assertFalse(instance.is_authorized_for_service("/test/ridiculous")) auth.current_user = auth.get_user("ACMitch") self.assertTrue(instance.is_authorized_for_service("/services/ServiceA")) self.assertTrue(instance.is_authorized_for_service("/services/ServiceB")) self.assertFalse(instance.is_authorized_for_service("/services/ServiceE")) self.assertFalse(instance.is_authorized_for_service("/test/ridiculous")) instance.assert_authorized_for_service("/services/ServiceD") self.assertRaises(AccessControlException, instance.assert_authorized_for_service, "/test/ridiculous" )
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 test_add_exception(self): ESAPI.intrusion_detector().add_exception( RuntimeError('message') ) ESAPI.intrusion_detector().add_exception( ValidationException("user message", "log message") ) ESAPI.intrusion_detector().add_exception( IntrusionException("user message", "log message") ) username = "******" password = "******" auth = ESAPI.authenticator() user = auth.create_user(username, password, password) user.enable() request = MockHttpRequest() response = MockHttpResponse() ESAPI.http_utilities().set_current_http(request, response) user.login_with_password(password) # Generate some exceptions to disable the account for i in range(15): IntegrityException( "IntegrityException %s" % i, "IntegrityException %s" % i ) self.assertFalse(user.is_logged_in()) self.assertTrue(user.is_locked())
def login_with_password(self, password): if password is None: self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Missing password: %(account_name)s") % {'account_name': self.account_name}) # Don't let disabled users log in if not self.is_enabled(): self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Disabled user attempt to login: %(account_name)s") % {'account_name': self.account_name}) # Don't let locked users log in if self.is_locked(): self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Locked user attempt to login: %(account_name)s") % {'account_name': self.account_name}) # Don't let expired users log in if self.is_expired(): self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Expired user attempt to login: %(account_name)s") % {'account_name': self.account_name}) self.logout() if self.verify_password(password): self._logged_in = True ESAPI.http_utilities().change_session_identifier( ESAPI.current_request()) ESAPI.authenticator().current_user = self self.last_login_time = datetime.now() self.last_host_address = ESAPI.http_utilities( ).get_current_request().remote_host self.logger.trace( Logger.SECURITY_SUCCESS, _("User logged in: %(account_name)s") % {'account_name': self.account_name}) else: self._logged_in = False self.last_failed_login_time = datetime.now() self.increment_failed_login_count() if self.get_failed_login_count() >= ESAPI.security_configuration( ).get_allowed_login_attempts(): self.lock() raise AuthenticationLoginException( _("Login failed"), _("Incorrect password provided for %(account_name)s") % {'account_name': self.account_name})
def test_is_authorized_for_function(self): instance = ESAPI.access_controller() auth = ESAPI.authenticator() auth.current_user = auth.get_user("ACAlice") self.assertTrue(instance.is_authorized_for_function("/FunctionA")) self.assertFalse(instance.is_authorized_for_function("/FunctionAdeny")) self.assertFalse(instance.is_authorized_for_function("/FunctionB")) self.assertFalse(instance.is_authorized_for_function("/FunctionBdeny")) self.assertTrue(instance.is_authorized_for_function("/FunctionC")) self.assertFalse(instance.is_authorized_for_function("/FunctionCdeny")) auth.current_user = auth.get_user("ACBob") self.assertFalse(instance.is_authorized_for_function("/FunctionA")) self.assertFalse(instance.is_authorized_for_function("/FunctionAdeny")) self.assertTrue(instance.is_authorized_for_function("/FunctionB")) self.assertFalse(instance.is_authorized_for_function("/FunctionBdeny")) self.assertTrue(instance.is_authorized_for_function("/FunctionD")) self.assertFalse(instance.is_authorized_for_function("/FunctionDdeny")) auth.current_user = auth.get_user("ACMitch") self.assertTrue(instance.is_authorized_for_function("/FunctionA")) self.assertFalse(instance.is_authorized_for_function("/FunctionAdeny")) self.assertTrue(instance.is_authorized_for_function("/FunctionB")) self.assertFalse(instance.is_authorized_for_function("/FunctionBdeny")) self.assertTrue(instance.is_authorized_for_function("/FunctionC")) self.assertFalse(instance.is_authorized_for_function("/FunctionCdeny")) instance.assert_authorized_for_function("/FunctionA") self.assertRaises(AccessControlException, instance.assert_authorized_for_function, "/FunctionDdeny" )
def test_add_exception(self): ESAPI.intrusion_detector().add_exception(RuntimeError('message')) ESAPI.intrusion_detector().add_exception( ValidationException("user message", "log message")) ESAPI.intrusion_detector().add_exception( IntrusionException("user message", "log message")) username = "******" password = "******" auth = ESAPI.authenticator() user = auth.create_user(username, password, password) user.enable() request = MockHttpRequest() response = MockHttpResponse() ESAPI.http_utilities().set_current_http(request, response) user.login_with_password(password) # Generate some exceptions to disable the account for i in range(15): IntegrityException("IntegrityException %s" % i, "IntegrityException %s" % i) self.assertFalse(user.is_logged_in()) self.assertTrue(user.is_locked())
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)
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 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)
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 test_csrf_token(self): username = "******" password = "******" user = ESAPI.authenticator().create_user(username, password, password) ESAPI.authenticator().current_user = user token = ESAPI.http_utilities().get_csrf_token() self.assertEquals(8, len(token)) request = MockHttpRequest() try: ESAPI.http_utilities().verify_csrf_token(request) self.fail() except: # expected pass request.GET[HTTPUtilities.CSRF_TOKEN_NAME] = token ESAPI.http_utilities().verify_csrf_token(request)
def test_exists(self): instance = ESAPI.authenticator() account_name = "testExists" password = instance.generate_strong_password() instance.create_user( account_name, password, password ) self.assertTrue(instance.exists(account_name)) instance.remove_user(account_name) self.assertFalse(instance.exists(account_name))
def test_generate_strong_password(self): instance = ESAPI.authenticator() old_password = '******' for i in range(100): try: new_password = instance.generate_strong_password() instance.verify_password_strength(new_password, old_password) except AuthenticationException, extra: print "FAILED >> " + new_password raise
def test_is_authorized_for_data(self): instance = ESAPI.access_controller() auth = ESAPI.authenticator() adminR = "java.util.ArrayList" adminRW = "java.lang.Math" userW = "java.util.Date" userRW = "java.lang.String" anyR = "java.io.BufferedReader" userAdminR = "java.util.Random" userAdminRW = "java.awt.event.MouseWheelEvent" undefined = "java.io.FileWriter" # test User auth.current_user = auth.get_user("ACAlice") self.assertTrue(instance.is_authorized_for_data("read", userRW)) self.assertFalse(instance.is_authorized_for_data("read", undefined)) self.assertFalse(instance.is_authorized_for_data("write", undefined)) self.assertFalse(instance.is_authorized_for_data("read", userW)) self.assertFalse(instance.is_authorized_for_data("read", adminRW)) self.assertTrue(instance.is_authorized_for_data("write", userRW)) self.assertTrue(instance.is_authorized_for_data("write", userW)) self.assertFalse(instance.is_authorized_for_data("write", anyR)) self.assertTrue(instance.is_authorized_for_data("read", anyR)) self.assertTrue(instance.is_authorized_for_data("read", userAdminR)) self.assertTrue(instance.is_authorized_for_data("write", userAdminRW)) # test Admin auth.current_user = auth.get_user("ACBob") self.assertTrue(instance.is_authorized_for_data("read", adminRW)) self.assertFalse(instance.is_authorized_for_data("read", undefined)) self.assertFalse(instance.is_authorized_for_data("write", undefined)) self.assertFalse(instance.is_authorized_for_data("read", userRW)) self.assertTrue(instance.is_authorized_for_data("write", adminRW)) self.assertFalse(instance.is_authorized_for_data("write", anyR)) self.assertTrue(instance.is_authorized_for_data("read", anyR)) self.assertTrue(instance.is_authorized_for_data("read", userAdminR)) self.assertTrue(instance.is_authorized_for_data("write", userAdminRW)) # test User/Admin auth.current_user = auth.get_user("ACMitch") self.assertTrue(instance.is_authorized_for_data("read", userRW)) self.assertFalse(instance.is_authorized_for_data("read", undefined)) self.assertFalse(instance.is_authorized_for_data("write", undefined)) self.assertFalse(instance.is_authorized_for_data("read", userW)) self.assertTrue(instance.is_authorized_for_data("read", adminR)) self.assertTrue(instance.is_authorized_for_data("write", userRW)) self.assertTrue(instance.is_authorized_for_data("write", userW)) self.assertFalse(instance.is_authorized_for_data("write", anyR)) self.assertTrue(instance.is_authorized_for_data("read", anyR)) self.assertTrue(instance.is_authorized_for_data("read", userAdminR)) self.assertTrue(instance.is_authorized_for_data("write", userAdminRW)) instance.assert_authorized_for_data("read", userRW) self.assertRaises(AccessControlException, instance.assert_authorized_for_data, "write", adminR )
def test_add_csrf_token(self): instance = ESAPI.authenticator() username = "******" password = '******' user = instance.create_user(username, password, password) instance.current_user = user csrf1 = ESAPI.http_utilities().add_csrf_token('/test1') self.assertTrue(csrf1.find('?') > -1) csrf2 = ESAPI.http_utilities().add_csrf_token('test1?one=two') self.assertTrue(csrf2.find('?') > -1)
def login_with_password(self, password): if password is None: self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Missing password: %(account_name)s") % {'account_name' : self.account_name}) # Don't let disabled users log in if not self.is_enabled(): self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Disabled user attempt to login: %(account_name)s") % {'account_name' : self.account_name}) # Don't let locked users log in if self.is_locked(): self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Locked user attempt to login: %(account_name)s") % {'account_name' : self.account_name}) # Don't let expired users log in if self.is_expired(): self.last_failed_login_time = datetime.now() self.increment_failed_login_count() raise AuthenticationLoginException( _("Login failed"), _("Expired user attempt to login: %(account_name)s") % {'account_name' : self.account_name}) self.logout() if self.verify_password( password ): self._logged_in = True ESAPI.http_utilities().change_session_identifier( ESAPI.current_request() ) ESAPI.authenticator().current_user = self self.last_login_time = datetime.now() self.last_host_address = ESAPI.http_utilities().get_current_request().remote_host self.logger.trace(Logger.SECURITY_SUCCESS, _("User logged in: %(account_name)s") % {'account_name' : self.account_name}) else: self._logged_in = False self.last_failed_login_time = datetime.now() self.increment_failed_login_count() if self.get_failed_login_count() >= ESAPI.security_configuration().get_allowed_login_attempts(): self.lock() raise AuthenticationLoginException( _("Login failed"), _("Incorrect password provided for %(account_name)s") % {'account_name' : self.account_name})
def add_csrf_token(self, href): user = ESAPI.authenticator().current_user if user.is_anonymous(): return href # If there are already parameters, append with an &, otherwise append # with a ? token = self.CSRF_TOKEN_NAME + "=" + user.csrf_token if href.find('?') == -1: # No params yet return href + "?" + token else: # href has params already return href + "&" + token
def add_csrf_token(self, href): user = ESAPI.authenticator().current_user if user.is_anonymous(): return href # If there are already parameters, append with an &, otherwise append # with a ? token = self.CSRF_TOKEN_NAME + "=" + user.csrf_token if href.find('?') == -1: # No params yet return href + "?" + token else: # href has params already return href + "&" + token
def test_login(self): instance = ESAPI.authenticator() username = "******" password = instance.generate_strong_password() user = instance.create_user(username, password, password) user.enable() request = MockHttpRequest() request.POST['username'] = username request.POST['password'] = password response = MockHttpResponse() test = instance.login( request, response ) self.assertTrue( test.is_logged_in() )
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 test_set_remember_token(self): instance = ESAPI.authenticator() account_name = "joestheplumber" password = instance.generate_strong_password() user = instance.create_user(account_name, password, password) user.enable() request = MockHttpRequest() request.POST['username'] = account_name request.POST['password'] = password response = MockHttpResponse() instance.login(request, response) max_age = 60 * 60 * 24 * 14 ESAPI.http_utilities().set_remember_token( password, max_age, "domain", '/', request, response )
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 change_session_identifier(self, request=None): temp = {} for key, value in request.session.items(): temp[key] = value # Kill old session and create a new one user = ESAPI.authenticator().current_user user.remove_session(request.session) request.session.invalidate() user.add_session(request.session) # Copy back the session content for key, value in temp.items(): request.session[key] = value return request.session
def change_session_identifier(self, request=None): temp = {} for key, value in request.session.items(): temp[key] = value # Kill old session and create a new one user = ESAPI.authenticator().current_user user.remove_session(request.session) request.session.invalidate() user.add_session(request.session) # Copy back the session content for key, value in temp.items(): request.session[key] = value return request.session
def test_add_event(self): username = "******" password = "******" auth = ESAPI.authenticator() user = auth.create_user(username, password, password) user.enable() request = MockHttpRequest() response = MockHttpResponse() ESAPI.http_utilities().set_current_http(request, response) user.login_with_password(password) # Generate some events to disable the account for i in range(15): ESAPI.intrusion_detector().add_event("test", "test message") self.assertTrue(user.is_locked())
def test_get_user_from_session(self): instance = ESAPI.authenticator() instance.logout() account_name = "sessionTester" password = instance.generate_strong_password() user = instance.create_user( account_name, password, password ) user.enable() request = MockHttpRequest() request.POST['username'] = account_name request.POST['password'] = password response = MockHttpResponse() ESAPI.http_utilities().set_current_http( request, response ) instance.login( request, response ) current_user = instance.get_user_from_session() self.assertEquals(user, current_user)
def test_add_event(self): username = "******" password = "******" auth = ESAPI.authenticator() user = auth.create_user(username, password, password) user.enable() request = MockHttpRequest() response = MockHttpResponse() ESAPI.http_utilities().set_current_http(request, response) user.login_with_password(password) # Generate some events to disable the account for i in range(15): ESAPI.intrusion_detector().add_event("test", "test message") self.assertTrue(user.is_locked())
def test_current_user(self): instance = ESAPI.authenticator() instance.logout() user1_name = "currentUser1" user2_name = "currentUser2" password = "******" user1 = instance.create_user(user1_name, password, password) user1.enable() request = MockHttpRequest() response = MockHttpResponse() ESAPI.http_utilities().set_current_http(request, response) user1.login_with_password(password) current_user = instance.current_user self.assertEquals(user1, current_user) user2 = instance.create_user(user2_name, password, password) instance.current_user = user2 self.assertFalse( current_user.account_name == user2.account_name )
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 test_is_authorized_for_url(self): instance = ESAPI.access_controller() auth = ESAPI.authenticator() auth.current_user = auth.get_user("ACAlice") self.assertFalse(instance.is_authorized_for_url("/nobody")) self.assertFalse(instance.is_authorized_for_url("/test/admin")) self.assertTrue(instance.is_authorized_for_url("/test/user")) self.assertTrue(instance.is_authorized_for_url("/test/all")) self.assertFalse(instance.is_authorized_for_url("/test/none")) self.assertTrue(instance.is_authorized_for_url("/test/none/test.gif")) self.assertFalse(instance.is_authorized_for_url("/test/none/test.exe")) self.assertTrue(instance.is_authorized_for_url("/test/none/test.png")) self.assertFalse(instance.is_authorized_for_url("/test/moderator")) self.assertTrue(instance.is_authorized_for_url("/test/profile")) self.assertFalse(instance.is_authorized_for_url("/upload")) auth.current_user = auth.get_user("ACBob") self.assertFalse(instance.is_authorized_for_url("/nobody")) self.assertTrue(instance.is_authorized_for_url("/test/admin")) self.assertFalse(instance.is_authorized_for_url("/test/user")) self.assertTrue(instance.is_authorized_for_url("/test/all")) self.assertFalse(instance.is_authorized_for_url("/test/none")) self.assertTrue(instance.is_authorized_for_url("/test/none/test.png")) self.assertFalse(instance.is_authorized_for_url("/test/moderator")) self.assertTrue(instance.is_authorized_for_url("/test/profile")) self.assertFalse(instance.is_authorized_for_url("/upload")) auth.current_user = auth.get_user("ACMitch") self.assertFalse(instance.is_authorized_for_url("/nobody")) self.assertTrue(instance.is_authorized_for_url("/test/admin")) self.assertTrue(instance.is_authorized_for_url("/test/user")) self.assertTrue(instance.is_authorized_for_url("/test/all")) self.assertFalse(instance.is_authorized_for_url("/test/none")) self.assertTrue(instance.is_authorized_for_url("/test/none/test.png")) self.assertFalse(instance.is_authorized_for_url("/test/moderator")) self.assertTrue(instance.is_authorized_for_url("/test/profile")) self.assertFalse(instance.is_authorized_for_url("/upload")) instance.assert_authorized_for_url( "/test/admin" ) self.assertRaises(AccessControlException, instance.assert_authorized_for_url, "/nobody" )
def take_security_action(self, action, message): """ Take a specified security action. In this implementation, acceptable actions are: log, disable, logout, and lock. @param action: the action to take. Ie "log", "disable", "logout" @param message: the message to log if the action is "log" """ if action == "log": self.logger.fatal(Logger.SECURITY_FAILURE, _("INTRUSION - ") + message) user = ESAPI.authenticator().current_user if user.is_anonymous(): return elif action == "disable": user.disable() elif action == "logout": user.logout() elif action == "lock": user.lock()
def take_security_action(self, action, message): """ Take a specified security action. In this implementation, acceptable actions are: log, disable, logout, and lock. @param action: the action to take. Ie "log", "disable", "logout" @param message: the message to log if the action is "log" """ if action == "log": self.logger.fatal( Logger.SECURITY_FAILURE, _("INTRUSION - ") + message ) user = ESAPI.authenticator().current_user if user.is_anonymous(): return elif action == "disable": user.disable() elif action == "logout": user.logout() elif action == "lock": user.lock()
def test_verify_password_strength(self): instance = ESAPI.authenticator() # Should catch the same middle part self.assertRaises(AuthenticationException, instance.verify_password_strength, "test56^$test", "abcdx56^$sl" ) # Complexity self.assertRaises(AuthenticationException, instance.verify_password_strength, "jeff" ) # Complexity self.assertRaises(AuthenticationException, instance.verify_password_strength, "JEFF" ) # Complexity self.assertRaises(AuthenticationException, instance.verify_password_strength, "1234" ) # Same self.assertRaises(AuthenticationException, instance.verify_password_strength, "password" ) # Weak self.assertRaises(AuthenticationException, instance.verify_password_strength, "-1" ) # Weak #self.assertRaises(AuthenticationException, instance.verify_password_strength, # "password123" ) # Weak self.assertRaises(AuthenticationException, instance.verify_password_strength, "test123" ) # Passes instance.verify_password_strength("jeffJEFF12!") instance.verify_password_strength("super calif ragil istic") instance.verify_password_strength("TONYTONYTONYTONY") instance.verify_password_strength(instance.generate_strong_password())
def match_rule(self, dictionary, key, action=None): """ Checks to see if the current user has access to the specified data, file, object, etc. If the user has access, as specified by the dictionary parameter, this method returns True. If the user does not have access or an exception is thrown, false is returned. @param dictionary: the map/dictionary containing the access rules @param key: the path of the requested file, url, object, etc. @return: True, if the user has access. Otherwise, False. """ # Get user's roles user = ESAPI.authenticator().current_user # Search for the first rule that matches the path and rules rule = self.search_for_rule(dictionary, user.roles, key) if action is None: return rule.allow else: return action.lower() in rule.actions
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 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 setUp(self): auth = ESAPI.authenticator() auth.clear_all_data() password = "******" # create user 'ACAlice' with 'user' role user = auth.get_user('ACAlice') if user is None: user = auth.create_user('ACAlice', password, password) user.add_role('user') # create user 'ACBob' with 'admin' role user = auth.get_user('ACBob') if user is None: user = auth.create_user('ACBob', password, password) user.add_role('admin') # create user 'ACMitch' with 'user' and 'admin' roles user = auth.get_user('ACMitch') if user is None: user = auth.create_user('ACMitch', password, password) user.add_role('user') user.add_role('admin')
def test_is_authorized_for_file(self): instance = ESAPI.access_controller() auth = ESAPI.authenticator() auth.current_user = auth.get_user("ACAlice") self.assertTrue(instance.is_authorized_for_file("/Dir/File1")) self.assertFalse(instance.is_authorized_for_file("/Dir/File2")) self.assertTrue(instance.is_authorized_for_file("/Dir/File3")) self.assertFalse(instance.is_authorized_for_file("/Dir/ridiculous")) auth.current_user = auth.get_user("ACBob") self.assertFalse(instance.is_authorized_for_file("/Dir/File1")) self.assertTrue(instance.is_authorized_for_file("/Dir/File2")) self.assertTrue(instance.is_authorized_for_file("/Dir/File4")) self.assertFalse(instance.is_authorized_for_file("/Dir/ridiculous")) auth.current_user = auth.get_user("ACMitch") self.assertTrue(instance.is_authorized_for_file("/Dir/File1")) self.assertTrue(instance.is_authorized_for_file("/Dir/File2")) self.assertFalse(instance.is_authorized_for_file("/Dir/File5")) self.assertFalse(instance.is_authorized_for_file("/Dir/ridiculous")) instance.assert_authorized_for_file("/Dir/File1") self.assertRaises(AccessControlException, instance.assert_authorized_for_file, "/Dir/File6" )
def change_password(self, old_password, new_password1, new_password2): ESAPI.authenticator().change_password(self, old_password, new_password1, new_password2)
def logout(self): return ESAPI.authenticator().logout(self)
def setUp(self): ESAPI.authenticator().clear_all_data()
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 verify_password(self, password): return ESAPI.authenticator().verify_password(self, password)
def get_csrf_token(self): user = ESAPI.authenticator().current_user if user is None: return None return user.csrf_token
def setUp(self): request = MockHttpRequest() response = MockHttpResponse() ESAPI.http_utilities().set_current_http(request, response) ESAPI.authenticator().logout() ESAPI.authenticator().clear_all_data()