diff options
| author | hmeland | 1999-06-11 14:29:54 +0000 |
|---|---|---|
| committer | hmeland | 1999-06-11 14:29:54 +0000 |
| commit | 9286ef4c5f1c9689dcd72f9731fdbdf8edb8546e (patch) | |
| tree | 1c24c793b53cab0f3e3c685ecb21209bb7ba08cd | |
| parent | 4b2a899ffd6325fb1eb223ad6633ce0f4ca2cd08 (diff) | |
| download | mailman-9286ef4c5f1c9689dcd72f9731fdbdf8edb8546e.tar.gz mailman-9286ef4c5f1c9689dcd72f9731fdbdf8edb8546e.tar.zst mailman-9286ef4c5f1c9689dcd72f9731fdbdf8edb8546e.zip | |
Changes to fix the CGI cookie security flaw reported by John Morton.
SecurityManager: New functions MakeCookie() and CheckCookie(). These
functions work with cookies containing cookie creation and expire
time, the client's IP number, and a checksum hash of these values as
well as a secret (the lists (encrypted) admin password).
admin.py, admindb.py and private.py: isAuthenticated now uses these
new cookie functions.
Diffstat (limited to '')
| -rw-r--r-- | Mailman/Cgi/admin.py | 4 | ||||
| -rw-r--r-- | Mailman/Cgi/admindb.py | 4 | ||||
| -rw-r--r-- | Mailman/Cgi/private.py | 17 | ||||
| -rw-r--r-- | Mailman/SecurityManager.py | 27 |
4 files changed, 38 insertions, 14 deletions
diff --git a/Mailman/Cgi/admin.py b/Mailman/Cgi/admin.py index 9e875d1f0..73a7b2cd9 100644 --- a/Mailman/Cgi/admin.py +++ b/Mailman/Cgi/admin.py @@ -50,7 +50,7 @@ def isAuthenticated(list, password=None, SECRET="SECRET"): AddErrorMessage(doc, 'Error: Incorrect admin password.') return 0 - token = `hash(list_name)` + token = list.MakeCookie() c = Cookie.Cookie() cookie_key = list_name + "-admin" c[cookie_key] = token @@ -60,7 +60,7 @@ def isAuthenticated(list, password=None, SECRET="SECRET"): if os.environ.has_key('HTTP_COOKIE'): c = Cookie.Cookie( os.environ['HTTP_COOKIE'] ) if c.has_key(list_name + "-admin"): - if c[list_name + "-admin"].value == `hash(list_name)`: + if list.CheckCookie(c[list_name + "-admin"].value): return 1 else: AddErrorMessage(doc, "error decoding authorization cookie") diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py index 3f3e20a2e..0f76c032c 100644 --- a/Mailman/Cgi/admindb.py +++ b/Mailman/Cgi/admindb.py @@ -34,7 +34,7 @@ def isAuthenticated(mlist, password=None, SECRET="SECRET"): AddErrorMessage(doc, 'Error: Incorrect admin password.') return 0 - token = `hash(list_name)` + token = list.MakeCookie() c = Cookie.Cookie() cookie_key = list_name + "-admin" c[cookie_key] = token @@ -44,7 +44,7 @@ def isAuthenticated(mlist, password=None, SECRET="SECRET"): if os.environ.has_key('HTTP_COOKIE'): c = Cookie.Cookie( os.environ['HTTP_COOKIE'] ) if c.has_key(list_name + "-admin"): - if c[list_name + "-admin"].value == `hash(list_name)`: + if list.CheckCookie(c[list_name + "-admin"].value): return 1 else: AddErrorMessage(doc, "error decoding authorization cookie") diff --git a/Mailman/Cgi/private.py b/Mailman/Cgi/private.py index 0fbdcede0..e46879371 100644 --- a/Mailman/Cgi/private.py +++ b/Mailman/Cgi/private.py @@ -32,9 +32,6 @@ import Mailman.mm_cfg LogStdErr("error", "private") - -SECRET = "secret" # XXX used for hashing - PAGE = ''' <html> <head> @@ -82,10 +79,15 @@ def GetListobj(list_name): return _list def isAuthenticated(list_name): + try: + listobj = GetListobj(list_name) + except Errors.MMUnknownListError: + print "\n<H3>List", repr(list_name), "not found.</h3>" + raise SystemExit if os.environ.has_key('HTTP_COOKIE'): c = Cookie.Cookie( os.environ['HTTP_COOKIE'] ) if c.has_key(list_name): - if c[list_name].value == `hash(list_name)`: + if listobj.CheckCookie(c[list_name].value): return 1 # No corresponding cookie. OK, then check for username, password # CGI variables @@ -108,17 +110,12 @@ def isAuthenticated(list_name): global login_attempted login_attempted=1 try: - listobj = GetListobj(list_name) - except Errors.MMUnknownListError: - print "\n<H3>List", repr(list_name), "not found.</h3>" - raise SystemExit - try: listobj.ConfirmUserPassword( username, password) except (Errors.MMBadUserError, Errors.MMBadPasswordError, Errors.MMNotAMemberError): return 0 - token = `hash(list_name)` + token = listobj.MakeCookie() c = Cookie.Cookie() c[list_name] = token print c # Output the cookie diff --git a/Mailman/SecurityManager.py b/Mailman/SecurityManager.py index 6a5d0f0a8..d60a93179 100644 --- a/Mailman/SecurityManager.py +++ b/Mailman/SecurityManager.py @@ -20,6 +20,7 @@ import os import string +import time import types import Crypt import Errors @@ -67,6 +68,32 @@ class SecurityManager: raise Errors.MMBadPasswordError return 1 + def MakeCookie(self): + client_ip = os.environ.get('REMOTE_ADDR') or '0.0.0.0' + issued = int(time.time()) + expires = issued + mm_cfg.ADMIN_COOKIE_LIFE + secret = self.password + mac = hash(secret + client_ip + `issued` + `expires`) + return [client_ip, issued, expires, mac] + + def CheckCookie(self, cookie): + if type(cookie) <> type([]): + return 0 + if len(cookie) <> 4: + return 0 + client_ip = os.environ.get('REMOTE_ADDR') or '0.0.0.0' + [for_ip, issued, expires, received_mac] = cookie + if for_ip <> client_ip: + return 0 + now = time.time() + if not issued < now < expires: + return 0 + secret = self.password + mac = hash(secret + client_ip + `issued` + `expires`) + if mac <> received_mac: + return 0 + return 1 + def ConfirmUserPassword(self, user, pw): """True if password is valid for site, list admin, or specific user.""" if self.ValidAdminPassword(pw): |
