VYPR
Critical severity9.1NVD Advisory· Published Jul 12, 2017· Updated May 13, 2026

CVE-2016-8638

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.

PackageAffected versionsPatched versions
ipsilonPyPI
>= 2.0.0, < 2.0.22.0.2
ipsilonPyPI
>= 1.2.0, < 1.2.11.2.1
ipsilonPyPI
>= 1.1.0, < 1.1.21.1.2
ipsilonPyPI
>= 1.0.0, < 1.0.31.0.3

Patches

4
1c48414877fc

Fix SAML2 multi-session vulnerability

https://github.com/ipsilon-project/ipsilonPatrick UiterwijkNov 4, 2016via ghsa
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)
    
64fc366c054f

Fix SAML2 multi-session vulnerability

https://github.com/ipsilon-project/ipsilonPatrick UiterwijkNov 4, 2016via ghsa
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)
    
a33303b6beb5

Fix SAML2 multi-session vulnerability

https://github.com/ipsilon-project/ipsilonPatrick UiterwijkNov 4, 2016via ghsa
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)
    
b4744a92d4fa

Fix SAML2 multi-session vulnerability

https://github.com/ipsilon-project/ipsilonPatrick UiterwijkNov 4, 2016via ghsa
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

News mentions

0

No linked articles in our index yet.