Commit 8e127f87 authored by Hanno Schlichting's avatar Hanno Schlichting

LP #1071067: Use a stronger random number generator and a constant time comparison function.

parent 41be01e2
...@@ -10,10 +10,12 @@ ...@@ -10,10 +10,12 @@
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE
# #
############################################################################ ############################################################################
import binascii import binascii
from cgi import escape from cgi import escape
from hashlib import sha256
import logging import logging
import random import os
import re import re
import string import string
import sys import sys
...@@ -63,6 +65,29 @@ TRAVERSAL_APPHANDLE = 'BrowserIdManager' ...@@ -63,6 +65,29 @@ TRAVERSAL_APPHANDLE = 'BrowserIdManager'
LOG = logging.getLogger('Zope.BrowserIdManager') LOG = logging.getLogger('Zope.BrowserIdManager')
# Use the system PRNG if possible
import random
try:
random = random.SystemRandom()
using_sysrandom = True
except NotImplementedError:
using_sysrandom = False
def _randint(start, end):
if not using_sysrandom:
# This is ugly, and a hack, but it makes things better than
# the alternative of predictability. This re-seeds the PRNG
# using a value that is hard for an attacker to predict, every
# time a random string is required. This may change the
# properties of the chosen random sequence slightly, but this
# is better than absolute predictability.
random.seed(sha256(
"%s%s%s" % (random.getstate(), time.time(), os.getpid())
).digest())
return random.randint(start, end)
def constructBrowserIdManager( def constructBrowserIdManager(
self, id=BROWSERID_MANAGER_NAME, title='', idname='_ZopeId', self, id=BROWSERID_MANAGER_NAME, title='', idname='_ZopeId',
location=('cookies', 'form'), cookiepath='/', cookiedomain='', location=('cookies', 'form'), cookiepath='/', cookiedomain='',
...@@ -553,7 +578,7 @@ def isAWellFormedBrowserId(bid, binerr=binascii.Error): ...@@ -553,7 +578,7 @@ def isAWellFormedBrowserId(bid, binerr=binascii.Error):
return None return None
def getNewBrowserId(randint=random.randint, maxint=99999999): def getNewBrowserId(randint=_randint, maxint=99999999):
""" Returns 19-character string browser id """ Returns 19-character string browser id
'AAAAAAAABBBBBBBB' 'AAAAAAAABBBBBBBB'
where: where:
...@@ -568,5 +593,4 @@ def getNewBrowserId(randint=random.randint, maxint=99999999): ...@@ -568,5 +593,4 @@ def getNewBrowserId(randint=random.randint, maxint=99999999):
An example is: 89972317A0C3EHnUi90w An example is: 89972317A0C3EHnUi90w
""" """
return '%08i%s' % (randint(0, maxint-1), getB64TStamp()) return '%08i%s' % (randint(0, maxint - 1), getB64TStamp())
...@@ -5,7 +5,7 @@ versions = versions ...@@ -5,7 +5,7 @@ versions = versions
[versions] [versions]
# Zope2-specific # Zope2-specific
Zope2 = Zope2 =
AccessControl = 3.0.5 AccessControl = 3.0.6
Acquisition = 4.0a1 Acquisition = 4.0a1
DateTime = 3.0.2 DateTime = 3.0.2
DocumentTemplate = 2.13.2 DocumentTemplate = 2.13.2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment