CVE-2016-8638
Description
A vulnerability in ipsilon 2.0 before 2.0.2, 1.2 before 1.2.1, 1.1 before 1.1.2, and 1.0 before 1.0.3 was found that allows attacker to log out active sessions of other users. This issue is related to how it tracks sessions, and allows an unauthenticated attacker to view and terminate active sessions from other users. It is also called a "SAML2 multi-session vulnerability."
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
ipsilonPyPI | >= 2.0.0, < 2.0.2 | 2.0.2 |
ipsilonPyPI | >= 1.2.0, < 1.2.1 | 1.2.1 |
ipsilonPyPI | >= 1.1.0, < 1.1.2 | 1.1.2 |
ipsilonPyPI | >= 1.0.0, < 1.0.3 | 1.0.3 |
Patches
41c48414877fcFix SAML2 multi-session vulnerability
4 files changed · +23 −25
ipsilon/login/common.py+5 −4 modified@@ -283,10 +283,11 @@ def __init__(self, *args, **kwargs): def root(self, *args, **kwargs): us = UserSession() - for provider in self.handlers: - self.debug("Calling logout for provider %s" % provider) - obj = self.handlers[provider] - obj() + if us.user is not None: + for provider in self.handlers: + self.debug("Calling logout for provider %s" % provider) + obj = self.handlers[provider] + obj() us.logout(self.user) return self._template('logout.html', title='Logout')
ipsilon/providers/saml2idp.py+1 −1 modified@@ -402,7 +402,7 @@ def idp_initiated_logout(self): saml_sessions = self.sessionfactory # pylint: disable=unused-variable (mech, session) = saml_sessions.get_next_logout( - logout_mechs=[lasso.SAML2_METADATA_BINDING_REDIRECT]) + logout_mechs=[lasso.SAML2_METADATA_BINDING_REDIRECT], user=us.user) if session is None: return
ipsilon/providers/saml2/logout.py+4 −4 modified@@ -251,7 +251,7 @@ def logout(self, message, relaystate=None, samlresponse=None): lasso.SAML2_METADATA_BINDING_REDIRECT, ] (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) while session: self.debug('Going to log out %s' % session.provider_id) @@ -279,7 +279,7 @@ def logout(self, message, relaystate=None, samlresponse=None): # log out self.debug('logging out provider id %s' % session.provider_id) indexes = saml_sessions.get_session_id_by_provider_id( - session.provider_id + session.provider_id, us.user ) self.debug('Requesting logout for sessions %s' % (indexes,)) req = logout.get_request() @@ -313,15 +313,15 @@ def logout(self, message, relaystate=None, samlresponse=None): self.error('Provider does not support SOAP') (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) # done while # All sessions should be logged out now. Respond to the # original request using the response we cached earlier. try: - session = saml_sessions.get_initial_logout() + session = saml_sessions.get_initial_logout(us.user) except ValueError: self.debug('SLO get_last_session() unable to find last session') raise cherrypy.HTTPError(400, 'Unable to determine logout state')
ipsilon/providers/saml2/sessions.py+13 −16 modified@@ -113,7 +113,6 @@ class SAMLSessionFactory(Log): """ def __init__(self, database_url): self._ss = SAML2SessionStore(database_url=database_url) - self.user = None def _data_to_samlsession(self, uuidval, data): """ @@ -143,8 +142,6 @@ def add_session(self, session_id, provider_id, user, login_session, :param request_id: The request ID of the Logout :param supported_logout_mechs: A list of logout protocols supported """ - self.user = user - timeout = cherrypy_config['tools.sessions.timeout'] t = datetime.timedelta(seconds=timeout * 60) expiration_time = datetime.datetime.now() + t @@ -175,11 +172,11 @@ def get_session_by_id(self, session_id): return self._data_to_samlsession(uuidval, data) - def get_session_id_by_provider_id(self, provider_id): + def get_session_id_by_provider_id(self, provider_id, user): """ Return a tuple of logged-in session IDs by provider_id """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) session_ids = [] for c in candidates: @@ -228,7 +225,7 @@ def start_logout(self, samlsession, relaystate=None, initial=True): self._ss.update_session(datum) def get_next_logout(self, peek=False, - logout_mechs=None): + logout_mechs=None, user=None): """ Get the next session in the logged-in state and move it to the logging_out state. Return the session that is @@ -246,7 +243,7 @@ def get_next_logout(self, peek=False, Returns a tuple of (mechanism, session) or (None, None) if no more sessions in LOGGED_IN state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) if logout_mechs is None: logout_mechs = [SAML2_METADATA_BINDING_REDIRECT, ] @@ -260,13 +257,13 @@ def get_next_logout(self, peek=False, return (mech, samlsession) return (None, None) - def get_initial_logout(self): + def get_initial_logout(self, user): """ Get the initial logout request. Raises ValueError if no sessions in INIT_LOGOUT state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) # FIXME: what does it mean if there are multiple in init? We # just return the first one for now. How do we know @@ -282,11 +279,11 @@ def get_initial_logout(self): def wipe_data(self): self._ss.wipe_data() - def dump(self): + def dump(self, user): """ Dump all sessions to debug log """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) count = 0 for c in candidates: @@ -314,13 +311,13 @@ def dump(self): SAML2_METADATA_BINDING_REDIRECT]) # Test finding sessions by provider - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='admin') assert(len(ids) == 1) sess3 = factory.add_session('_345678', provider2, "testuser", "<Login/>", '_3456', [SAML2_METADATA_BINDING_REDIRECT]) - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='testuser') assert(len(ids) == 2) # Test finding sessions by session ID @@ -343,13 +340,13 @@ def dump(self): test2 = factory.get_session_by_id('_789012') factory.start_logout(test2, initial=True) - (lmech, test3) = factory.get_next_logout() + (lmech, test3) = factory.get_next_logout(user='admin') assert(test3.session_id == '_345678') - test4 = factory.get_initial_logout() + test4 = factory.get_initial_logout(user='admin') assert(test4.session_id == '_789012') # Even though we've started logout, make sure we can still find # all sessions for a provider. - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='admin') assert(len(ids) == 2)
64fc366c054fFix SAML2 multi-session vulnerability
4 files changed · +20 −22
ipsilon/login/common.py+5 −4 modified@@ -281,10 +281,11 @@ def __init__(self, *args, **kwargs): def root(self, *args, **kwargs): us = UserSession() - for provider in self.handlers: - self.debug("Calling logout for provider %s" % provider) - obj = self.handlers[provider] - obj() + if us.user is not None: + for provider in self.handlers: + self.debug("Calling logout for provider %s" % provider) + obj = self.handlers[provider] + obj() us.logout(self.user) return self._template('logout.html', title='Logout')
ipsilon/providers/saml2idp.py+1 −1 modified@@ -400,7 +400,7 @@ def idp_initiated_logout(self): user = us.get_user() saml_sessions = self.sessionfactory - session = saml_sessions.get_next_logout() + session = saml_sessions.get_next_logout(us.user) if session is None: return
ipsilon/providers/saml2/logout.py+3 −3 modified@@ -217,7 +217,7 @@ def logout(self, message, relaystate=None, samlresponse=None): # Fall through to handle any remaining sessions. # Find the next SP to logout and send a LogoutRequest - session = saml_sessions.get_next_logout() + session = saml_sessions.get_next_logout(us.user) if session: self.debug('Going to log out %s' % session.provider_id) @@ -241,7 +241,7 @@ def logout(self, message, relaystate=None, samlresponse=None): # log out self.debug('logging out provider id %s' % session.provider_id) indexes = saml_sessions.get_session_id_by_provider_id( - session.provider_id + session.provider_id, us.user ) self.debug('Requesting logout for sessions %s' % indexes) req = logout.get_request() @@ -262,7 +262,7 @@ def logout(self, message, relaystate=None, samlresponse=None): # response we cached earlier. try: - session = saml_sessions.get_initial_logout() + session = saml_sessions.get_initial_logout(us.user) except ValueError: self.debug('SLO get_last_session() unable to find last session') raise cherrypy.HTTPError(400, 'Unable to determine logout state')
ipsilon/providers/saml2/sessions.py+11 −14 modified@@ -103,7 +103,6 @@ class SAMLSessionFactory(Log): """ def __init__(self, database_url): self._ss = SAML2SessionStore(database_url=database_url) - self.user = None def _data_to_samlsession(self, uuidval, data): """ @@ -125,8 +124,6 @@ def add_session(self, session_id, provider_id, user, login_session, """ Add a new login session to the table. """ - self.user = user - timeout = cherrypy_config['tools.sessions.timeout'] t = datetime.timedelta(seconds=timeout * 60) expiration_time = datetime.datetime.now() + t @@ -157,11 +154,11 @@ def get_session_by_id(self, session_id): return self._data_to_samlsession(uuidval, data) - def get_session_id_by_provider_id(self, provider_id): + def get_session_id_by_provider_id(self, provider_id, user): """ Return a tuple of logged-in session IDs by provider_id """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) session_ids = [] for c in candidates: @@ -209,7 +206,7 @@ def start_logout(self, samlsession, relaystate=None, initial=True): datum = samlsession.convert() self._ss.update_session(datum) - def get_next_logout(self, peek=False): + def get_next_logout(self, user, peek=False): """ Get the next session in the logged-in state and move it to the logging_out state. Return the session that is @@ -221,7 +218,7 @@ def get_next_logout(self, peek=False): Return None if no more sessions in LOGGED_IN state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) for c in candidates: key = c.keys()[0] @@ -231,13 +228,13 @@ def get_next_logout(self, peek=False): return samlsession return None - def get_initial_logout(self): + def get_initial_logout(self, user): """ Get the initial logout request. Return None if no sessions in INIT_LOGOUT state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) # FIXME: what does it mean if there are multiple in init? We # just return the first one for now. How do we know @@ -253,11 +250,11 @@ def get_initial_logout(self): def wipe_data(self): self._ss.wipe_data() - def dump(self): + def dump(self, user): """ Dump all sessions to debug log """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) count = 0 for c in candidates: @@ -280,11 +277,11 @@ def dump(self): sess2 = factory.add_session('_789012', provider2, "testuser", "<Login/>") # Test finding sessions by provider - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, 'admin') assert(len(ids) == 1) sess3 = factory.add_session('_345678', provider2, "testuser", "<Login/>") - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, 'testuser') assert(len(ids) == 2) # Test finding sessions by session ID @@ -315,5 +312,5 @@ def dump(self): # Even though we've started logout, make sure we can still find # all sessions for a provider. - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, 'admin') assert(len(ids) == 2)
a33303b6beb5Fix SAML2 multi-session vulnerability
4 files changed · +24 −26
ipsilon/login/common.py+5 −4 modified@@ -374,10 +374,11 @@ def __init__(self, *args, **kwargs): def root(self, *args, **kwargs): us = UserSession() - for provider in self.handlers: - self.debug("Calling logout for provider %s" % provider) - obj = self.handlers[provider] - obj() + if us.user is not None: + for provider in self.handlers: + self.debug("Calling logout for provider %s" % provider) + obj = self.handlers[provider] + obj() us.logout(self.user) return self._template('logout.html', title='Logout')
ipsilon/providers/saml2idp.py+1 −1 modified@@ -410,7 +410,7 @@ def idp_initiated_logout(self): saml_sessions = self.sessionfactory # pylint: disable=unused-variable (mech, session) = saml_sessions.get_next_logout( - logout_mechs=[lasso.SAML2_METADATA_BINDING_REDIRECT]) + logout_mechs=[lasso.SAML2_METADATA_BINDING_REDIRECT], user=us.user) if session is None: return
ipsilon/providers/saml2/logout.py+5 −5 modified@@ -278,7 +278,7 @@ def logout(self, message, relaystate=None, samlresponse=None): lasso.SAML2_METADATA_BINDING_REDIRECT, ] (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) while session: self.debug('Going to log out %s' % session.provider_id) @@ -302,7 +302,7 @@ def logout(self, message, relaystate=None, samlresponse=None): ) saml_sessions.remove_session(session) (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) continue try: @@ -316,7 +316,7 @@ def logout(self, message, relaystate=None, samlresponse=None): # log out self.debug('logging out provider id %s' % session.provider_id) indexes = saml_sessions.get_session_id_by_provider_id( - session.provider_id + session.provider_id, us.user ) self.debug('Requesting logout for sessions %s' % (indexes,)) req = logout.get_request() @@ -350,15 +350,15 @@ def logout(self, message, relaystate=None, samlresponse=None): self.error('Provider does not support SOAP') (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) # done while # All sessions should be logged out now. Respond to the # original request using the response we cached earlier. try: - session = saml_sessions.get_initial_logout() + session = saml_sessions.get_initial_logout(us.user) except ValueError: self.debug('SLO get_last_session() unable to find last session') raise cherrypy.HTTPError(400, 'Unable to determine logout state')
ipsilon/providers/saml2/sessions.py+13 −16 modified@@ -113,7 +113,6 @@ class SAMLSessionFactory(Log): """ def __init__(self, database_url): self._ss = SAML2SessionStore(database_url=database_url) - self.user = None def _data_to_samlsession(self, uuidval, data): """ @@ -143,8 +142,6 @@ def add_session(self, session_id, provider_id, user, login_session, :param request_id: The request ID of the Logout :param supported_logout_mechs: A list of logout protocols supported """ - self.user = user - timeout = cherrypy_config['tools.sessions.timeout'] t = datetime.timedelta(seconds=timeout * 60) expiration_time = datetime.datetime.now() + t @@ -175,11 +172,11 @@ def get_session_by_id(self, session_id): return self._data_to_samlsession(uuidval, data) - def get_session_id_by_provider_id(self, provider_id): + def get_session_id_by_provider_id(self, provider_id, user): """ Return a tuple of logged-in session IDs by provider_id """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) session_ids = [] for c in candidates: @@ -228,7 +225,7 @@ def start_logout(self, samlsession, relaystate=None, initial=True): self._ss.update_session(datum) def get_next_logout(self, peek=False, - logout_mechs=None): + logout_mechs=None, user=None): """ Get the next session in the logged-in state and move it to the logging_out state. Return the session that is @@ -246,7 +243,7 @@ def get_next_logout(self, peek=False, Returns a tuple of (mechanism, session) or (None, None) if no more sessions in LOGGED_IN state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) if logout_mechs is None: logout_mechs = [SAML2_METADATA_BINDING_REDIRECT, ] @@ -260,13 +257,13 @@ def get_next_logout(self, peek=False, return (mech, samlsession) return (None, None) - def get_initial_logout(self): + def get_initial_logout(self, user): """ Get the initial logout request. Raises ValueError if no sessions in INIT_LOGOUT state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) # FIXME: what does it mean if there are multiple in init? We # just return the first one for now. How do we know @@ -282,11 +279,11 @@ def get_initial_logout(self): def wipe_data(self): self._ss.wipe_data() - def dump(self): + def dump(self, user): """ Dump all sessions to debug log """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) count = 0 for c in candidates: @@ -314,13 +311,13 @@ def dump(self): SAML2_METADATA_BINDING_REDIRECT]) # Test finding sessions by provider - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='admin') assert(len(ids) == 1) sess3 = factory.add_session('_345678', provider2, "testuser", "<Login/>", '_3456', [SAML2_METADATA_BINDING_REDIRECT]) - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='testuser') assert(len(ids) == 2) # Test finding sessions by session ID @@ -343,13 +340,13 @@ def dump(self): test2 = factory.get_session_by_id('_789012') factory.start_logout(test2, initial=True) - (lmech, test3) = factory.get_next_logout() + (lmech, test3) = factory.get_next_logout(user='admin') assert(test3.session_id == '_345678') - test4 = factory.get_initial_logout() + test4 = factory.get_initial_logout(user='admin') assert(test4.session_id == '_789012') # Even though we've started logout, make sure we can still find # all sessions for a provider. - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='admin') assert(len(ids) == 2)
b4744a92d4faFix SAML2 multi-session vulnerability
4 files changed · +24 −26
ipsilon/login/common.py+5 −4 modified@@ -369,10 +369,11 @@ def __init__(self, *args, **kwargs): def root(self, *args, **kwargs): us = UserSession() - for provider in self.handlers: - self.debug("Calling logout for provider %s" % provider) - obj = self.handlers[provider] - obj() + if us.user is not None: + for provider in self.handlers: + self.debug("Calling logout for provider %s" % provider) + obj = self.handlers[provider] + obj() us.logout(self.user) return self._template('logout.html', title='Logout')
ipsilon/providers/saml2idp.py+1 −1 modified@@ -410,7 +410,7 @@ def idp_initiated_logout(self): saml_sessions = self.sessionfactory # pylint: disable=unused-variable (mech, session) = saml_sessions.get_next_logout( - logout_mechs=[lasso.SAML2_METADATA_BINDING_REDIRECT]) + logout_mechs=[lasso.SAML2_METADATA_BINDING_REDIRECT], user=us.user) if session is None: return
ipsilon/providers/saml2/logout.py+5 −5 modified@@ -278,7 +278,7 @@ def logout(self, message, relaystate=None, samlresponse=None): lasso.SAML2_METADATA_BINDING_REDIRECT, ] (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) while session: self.debug('Going to log out %s' % session.provider_id) @@ -302,7 +302,7 @@ def logout(self, message, relaystate=None, samlresponse=None): ) saml_sessions.remove_session(session) (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) continue try: @@ -316,7 +316,7 @@ def logout(self, message, relaystate=None, samlresponse=None): # log out self.debug('logging out provider id %s' % session.provider_id) indexes = saml_sessions.get_session_id_by_provider_id( - session.provider_id + session.provider_id, us.user ) self.debug('Requesting logout for sessions %s' % (indexes,)) req = logout.get_request() @@ -350,15 +350,15 @@ def logout(self, message, relaystate=None, samlresponse=None): self.error('Provider does not support SOAP') (logout_mech, session) = saml_sessions.get_next_logout( - logout_mechs=logout_order) + logout_mechs=logout_order, user=us.user) # done while # All sessions should be logged out now. Respond to the # original request using the response we cached earlier. try: - session = saml_sessions.get_initial_logout() + session = saml_sessions.get_initial_logout(us.user) except ValueError: self.debug('SLO get_last_session() unable to find last session') raise cherrypy.HTTPError(400, 'Unable to determine logout state')
ipsilon/providers/saml2/sessions.py+13 −16 modified@@ -113,7 +113,6 @@ class SAMLSessionFactory(Log): """ def __init__(self, database_url): self._ss = SAML2SessionStore(database_url=database_url) - self.user = None def _data_to_samlsession(self, uuidval, data): """ @@ -143,8 +142,6 @@ def add_session(self, session_id, provider_id, user, login_session, :param request_id: The request ID of the Logout :param supported_logout_mechs: A list of logout protocols supported """ - self.user = user - timeout = cherrypy_config['tools.sessions.timeout'] t = datetime.timedelta(seconds=timeout * 60) expiration_time = datetime.datetime.now() + t @@ -175,11 +172,11 @@ def get_session_by_id(self, session_id): return self._data_to_samlsession(uuidval, data) - def get_session_id_by_provider_id(self, provider_id): + def get_session_id_by_provider_id(self, provider_id, user): """ Return a tuple of logged-in session IDs by provider_id """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) session_ids = [] for c in candidates: @@ -228,7 +225,7 @@ def start_logout(self, samlsession, relaystate=None, initial=True): self._ss.update_session(datum) def get_next_logout(self, peek=False, - logout_mechs=None): + logout_mechs=None, user=None): """ Get the next session in the logged-in state and move it to the logging_out state. Return the session that is @@ -246,7 +243,7 @@ def get_next_logout(self, peek=False, Returns a tuple of (mechanism, session) or (None, None) if no more sessions in LOGGED_IN state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) if logout_mechs is None: logout_mechs = [SAML2_METADATA_BINDING_REDIRECT, ] @@ -260,13 +257,13 @@ def get_next_logout(self, peek=False, return (mech, samlsession) return (None, None) - def get_initial_logout(self): + def get_initial_logout(self, user): """ Get the initial logout request. Raises ValueError if no sessions in INIT_LOGOUT state. """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) # FIXME: what does it mean if there are multiple in init? We # just return the first one for now. How do we know @@ -282,11 +279,11 @@ def get_initial_logout(self): def wipe_data(self): self._ss.wipe_data() - def dump(self): + def dump(self, user): """ Dump all sessions to debug log """ - candidates = self._ss.get_user_sessions(self.user) + candidates = self._ss.get_user_sessions(user) count = 0 for c in candidates: @@ -314,13 +311,13 @@ def dump(self): SAML2_METADATA_BINDING_REDIRECT]) # Test finding sessions by provider - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='admin') assert(len(ids) == 1) sess3 = factory.add_session('_345678', provider2, "testuser", "<Login/>", '_3456', [SAML2_METADATA_BINDING_REDIRECT]) - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='testuser') assert(len(ids) == 2) # Test finding sessions by session ID @@ -343,13 +340,13 @@ def dump(self): test2 = factory.get_session_by_id('_789012') factory.start_logout(test2, initial=True) - (lmech, test3) = factory.get_next_logout() + (lmech, test3) = factory.get_next_logout(user='admin') assert(test3.session_id == '_345678') - test4 = factory.get_initial_logout() + test4 = factory.get_initial_logout(user='admin') assert(test4.session_id == '_789012') # Even though we've started logout, make sure we can still find # all sessions for a provider. - ids = factory.get_session_id_by_provider_id(provider2) + ids = factory.get_session_id_by_provider_id(provider2, user='admin') assert(len(ids) == 2)
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
15- pagure.io/ipsilon/c/511fa8b7001c2f9a42301aa1d4b85aaf170a461cnvdPatchVendor AdvisoryWEB
- www.securityfocus.com/bid/94439nvdThird Party AdvisoryVDB EntryWEB
- bugzilla.redhat.com/show_bug.cginvdIssue TrackingThird Party AdvisoryWEB
- github.com/advisories/GHSA-376m-3rm2-9jm6ghsaADVISORY
- ipsilon-project.org/advisory/CVE-2016-8638.txtnvdVendor AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2016-8638ghsaADVISORY
- rhn.redhat.com/errata/RHSA-2016-2809.htmlnvdWEB
- access.redhat.com/errata/RHSA-2016:2809ghsaWEB
- access.redhat.com/security/cve/CVE-2016-8638ghsaWEB
- bugzilla.redhat.com/show_bug.cgighsaWEB
- github.com/ipsilon-project/ipsilon/commit/1c48414877fc110652b6078a29529972c7ec9122ghsaWEB
- github.com/ipsilon-project/ipsilon/commit/64fc366c054fc6af1d9d2692902db169884b5f78ghsaWEB
- github.com/ipsilon-project/ipsilon/commit/a33303b6beb5c316d7c18b23566b7666a4e307a4ghsaWEB
- github.com/ipsilon-project/ipsilon/commit/b4744a92d4fa7f6d7ade0ae2d99a2dc0ea94734dghsaWEB
- ipsilon-project.org/release/2.1.0.htmlnvdWEB
News mentions
0No linked articles in our index yet.