diff roundup/cgi/client.py @ 5202:47bd81998ddc

My testing was with dbm backends which do an automatic commit on the otk database. My tests used a mock for the otk database because I don't now how to get a real db into the test, so they didn't test the rdbms code paths. Once I committed to upstream I updated my sqlite based production tracker and boom. Couldn't log in with csrf_enforce = required. I was missing calls to commit to the db which is required for rdbms backends. Added those and also removed redundant code where I was deleting the otk in a few places. Once it's used and I have retrieved data from it, I don't need it. Nuke it upstream from all the code paths that will exit the routine so I don't have to delete in each code path.
author John Rouillard <rouilj@ieee.org>
date Sat, 18 Mar 2017 19:16:56 -0400
parents a9ace22e0a2f
children 7da56980754d
line wrap: on
line diff
--- a/roundup/cgi/client.py	Sat Mar 18 16:59:01 2017 -0400
+++ b/roundup/cgi/client.py	Sat Mar 18 19:16:56 2017 -0400
@@ -1050,11 +1050,12 @@
         if "@csrf" not in self.form:
             if enforce == 'required':
                 self.add_error_message(self._("No csrf token found"))
+                logger.error(self._("required csrf field missing for user%s"), user)
                 return False
             else:
                 if enforce == 'logfailure':
                     # FIXME include url
-                    logger.warning(self._("csrf field missing for user%s"), user)
+                    logger.warning(self._("required csrf field missing for user%s"), user)
                 return True
 
         key=self.form['@csrf'].value
@@ -1093,28 +1094,29 @@
            self.form["@action"].value == "Login":
             if header_pass > 0:
                 otks.destroy(key)
+                self.db.commit()
                 return True
             else:
                 self.add_error_message("Reload window before logging in.")
         '''
 
+        # The key has been used or compromised. Delete it to prevent replay.
+        otks.destroy(key)
+        self.db.commit()
+
         if uid != user:
             if enforce in ('required', "yes"):
                 self.add_error_message(self._("Invalid csrf token found: %s")%key)
-                otks.destroy(key)
                 return False
             elif enforce == 'logfailure':
                     logger.warning(self._("csrf uid mismatch for user%s."), user)
-        if self.session_api._sid != sid:
+        if current_session != sid:
             if enforce in ('required', "yes"):
                 self.add_error_message(self._(
                     "Invalid csrf session found: %s")%key)
-                otks.destroy(key)
                 return False
             elif enforce == 'logfailure':
                     logger.warning(self._("csrf session mismatch for user%s."), user)
-        # Remove the key so a previous csrf key can't be replayed.
-        otks.destroy(key)
         return True
 
     def opendb(self, username):

Roundup Issue Tracker: http://roundup-tracker.org/