Skip to content

Commit 9fd22d5

Browse files
committed
Fix expiration dates and expire csrf tokens properly
In client.py: add explicit expiration of csrf tokens to handle_csrf. There is a clean_up() that runs on every client connection before handle)csrf is invoked, but it only cleans every hour. With short lived tokens this is insufficient. Also remove debugging. In templating.py fix values for seconds/week and minutes per week. The original values were shifted/transposed and an order of magnitude off. In test_templating.py again fix seconds/week constant.
1 parent 6a88660 commit 9fd22d5

File tree

3 files changed

+28
-14
lines changed

3 files changed

+28
-14
lines changed

roundup/cgi/client.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,18 +1086,25 @@ def handle_csrf(self, xmlrpc=False):
10861086
logger.warning(self._("required csrf field missing for user%s"), user)
10871087
return True
10881088

1089+
# Expire old csrf tokens now so we don't use them. These will
1090+
# be committed after the otks.destroy below. Note that the
1091+
# self.clean_up run as part of determine_user() will run only
1092+
# once an hour. If we have short lived (e.g. 5 minute) keys
1093+
# they will live too long if we depend on clean_up. So we do
1094+
# our own.
1095+
otks.clean()
1096+
10891097
key=self.form['@csrf'].value
10901098
uid = otks.get(key, 'uid', default=None)
10911099
sid = otks.get(key, 'sid', default=None)
1092-
if __debug__:
1093-
ts = otks.get(key, '__timestamp', default=None)
1094-
print("Found key %s for user%s sess: %s, ts %s, time %s"%(key, uid, sid, ts, time.time()))
1095-
current_session = self.session_api._sid
10961100

1097-
# The key has been used or compromised. Delete it to prevent replay.
1101+
# The key has been used or compromised.
1102+
# Delete it to prevent replay.
10981103
otks.destroy(key)
10991104
self.db.commit()
11001105

1106+
current_session = self.session_api._sid
1107+
11011108
'''
11021109
# I think now that LogoutAction redirects to
11031110
# self.base ([tracker] web parameter in config.ini),

roundup/cgi/templating.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,13 @@ def anti_csrf_nonce(self, client, lifetime=None):
9797
# That's the cleanup period hardcoded in otk.clean().
9898
# If a user wants a 10 minute lifetime calculate
9999
# 10 minutes newer than 1 week ago.
100-
# lifetime - 10800 (number of minutes in a week)
100+
# lifetime - 10080 (number of minutes in a week)
101101
# convert to seconds and add (possible negative number)
102-
# from time.time().
102+
# to current time (time.time()).
103+
ts = time.time() + ((lifetime - 10080) * 60)
103104
otks.set(key, uid=client.db.getuid(),
104105
sid=client.session_api._sid,
105-
__timestamp=time.time() + ((lifetime - 10800) * 60) )
106+
__timestamp=ts )
106107
client.db.commit()
107108
return key
108109

test/test_templating.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,13 @@ def test_anti_csrf_nonce(self):
143143
'''
144144

145145
# the value below is number of seconds in a week.
146-
week_seconds = 648000
146+
week_seconds = 604800
147+
148+
otks=self.client.db.getOTKManager()
149+
147150
for test in [ 'module', 'template', 'default_time' ]:
151+
print "Testing:", test
152+
148153
if test == 'module':
149154
# test the module function
150155
nonce1 = anti_csrf_nonce(self, self.client, lifetime=1)
@@ -162,7 +167,6 @@ def test_anti_csrf_nonce(self):
162167
greater_than = week_seconds - 10 * 60
163168

164169
self.assertEqual(len(nonce1), 64)
165-
otks=self.client.db.getOTKManager()
166170

167171
uid = otks.get(nonce1, 'uid', default=None)
168172
sid = otks.get(nonce1, 'sid', default=None)
@@ -171,17 +175,19 @@ def test_anti_csrf_nonce(self):
171175
self.assertEqual(uid, 10)
172176
self.assertEqual(sid, self.client.session_api._sid)
173177

174-
ts = time.time()
178+
now = time.time()
179+
180+
print "now, timestamp, greater, difference", \
181+
now, timestamp, greater_than, now - timestamp
182+
175183

176184
# lower bound of the difference is above. Upper bound
177185
# of difference is run time between time.time() in
178186
# the call to anti_csrf_nonce and the time.time() call
179187
# that assigns ts above. I declare that difference
180188
# to be less than 1 second for this to pass.
181189
self.assertEqual(True,
182-
greater_than < ts - timestamp < (greater_than + 1) )
183-
184-
print "completed", test
190+
greater_than <= now - timestamp < (greater_than + 1) )
185191

186192
def test_string_url_quote(self):
187193
''' test that urlquote quotes the string '''

0 commit comments

Comments
 (0)