[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/SessionService - CookieSessionService.py:1.2
Itamar Shtull-Trauring
zope@itamarst.org
Thu, 5 Dec 2002 12:10:35 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/SessionService
In directory cvs.zope.org:/tmp/cvs-serv31554
Modified Files:
CookieSessionService.py
Log Message:
make session id cookies unforgeable, although session hijacking is still possible
=== Zope3/lib/python/Zope/App/OFS/Services/SessionService/CookieSessionService.py 1.1 => 1.2 ===
--- Zope3/lib/python/Zope/App/OFS/Services/SessionService/CookieSessionService.py:1.1 Wed Dec 4 16:46:16 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/SessionService/CookieSessionService.py Thu Dec 5 12:10:35 2002
@@ -19,7 +19,7 @@
"""
# System imports
-import sha, time, string, random
+import sha, time, string, random, hmac
# Zope3 imports
from Persistence import Persistent
@@ -32,6 +32,10 @@
cookieSafeTrans = string.maketrans("+/", "-.")
+def digestEncode(s):
+ """Encode SHA digest for cookie."""
+ return s.encode("base64")[:-2].translate(cookieSafeTrans)
+
class CookieSessionService(Persistent):
"""Session service implemented using cookies."""
@@ -41,17 +45,25 @@
def __init__(self):
self.dataManagers = PersistentDict()
self.namespace = "zope3-cs-%x" % (int(time.time()) - 1000000000)
+ self.secret = "%.20f" % random.random()
def generateUniqueId(self):
"""Generate a new, random, unique id."""
data = "%.20f%.20f%.20f" % (random.random(), time.time(), time.clock())
digest = sha.sha(data).digest()
- return digest.encode("base64")[:-2].translate(cookieSafeTrans)
+ s = digestEncode(digest)
+ # we store a HMAC of the random value together with it, which makes
+ # our session ids unforgeable.
+ mac = hmac.new(s, self.secret, digestmod=sha).digest()
+ return s + digestEncode(mac)
def getRequestId(self, request):
"""Return the sessionId encoded in request or None if it's non-existent."""
sid = request.cookies.get(self.namespace)
- if sid is None or len(sid) != 27:
+ if sid is None or len(sid) != 54:
+ return None
+ s, mac = sid[:27], sid[27:]
+ if digestEncode(hmac.new(s, self.secret, digestmod=sha).digest()) != mac:
return None
else:
return sid