From 0d11dc90ee6fc9cc61d32ca3ea6819ca95ac1c12 Mon Sep 17 00:00:00 2001 From: Mark Sapiro Date: Mon, 5 Jun 2017 20:48:34 -0700 Subject: Defend against CGI requests with multiple values for the same parameter. --- Mailman/Cgi/admin.py | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'Mailman/Cgi/admin.py') diff --git a/Mailman/Cgi/admin.py b/Mailman/Cgi/admin.py index 41875533..f96b175a 100644 --- a/Mailman/Cgi/admin.py +++ b/Mailman/Cgi/admin.py @@ -87,7 +87,7 @@ def main(): # If the user is not authenticated, we're done. cgidata = cgi.FieldStorage(keep_blank_values=1) try: - cgidata.getvalue('csrf_token', '') + cgidata.getfirst('csrf_token', '') except TypeError: # Someone crafted a POST with a bad Content-Type:. doc = Document() @@ -105,17 +105,17 @@ def main(): 'legend'] params = cgidata.keys() if set(params) - set(safe_params): - csrf_checked = csrf_check(mlist, cgidata.getvalue('csrf_token')) + csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token')) else: csrf_checked = True # if password is present, void cookie to force password authentication. - if cgidata.getvalue('adminpw'): + if cgidata.getfirst('adminpw'): os.environ['HTTP_COOKIE'] = '' csrf_checked = True if not mlist.WebAuthenticate((mm_cfg.AuthListAdmin, mm_cfg.AuthSiteAdmin), - cgidata.getvalue('adminpw', '')): + cgidata.getfirst('adminpw', '')): if cgidata.has_key('adminpw'): # This is a re-authorization attempt msg = Bold(FontSize('+1', _('Authorization failed.'))).Format() @@ -155,7 +155,7 @@ def main(): if qsenviron: parsedqs = cgi.parse_qs(qsenviron) if cgidata.has_key('VARHELP'): - varhelp = cgidata.getvalue('VARHELP') + varhelp = cgidata.getfirst('VARHELP') elif parsedqs: # POST methods, even if their actions have a query string, don't get # put into FieldStorage's keys :-( @@ -913,7 +913,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): _('(help)')).Format() table.AddRow([Label(_('Find member %(link)s:')), TextBox('findmember', - value=cgidata.getvalue('findmember', '')), + value=cgidata.getfirst('findmember', '')), SubmitButton('findmember_btn', _('Search...'))]) container.AddItem(table) container.AddItem('

') @@ -926,7 +926,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): all = [_m.encode() for _m in mlist.getMembers()] all.sort(lambda x, y: cmp(x.lower(), y.lower())) # See if the query has a regular expression - regexp = cgidata.getvalue('findmember', '').strip() + regexp = cgidata.getfirst('findmember', '').strip() try: regexp = regexp.decode(Utils.GetCharSet(mlist.preferred_language)) except UnicodeDecodeError: @@ -1385,14 +1385,14 @@ def submit_button(name='submit'): def change_options(mlist, category, subcat, cgidata, doc): def safeint(formvar, defaultval=None): try: - return int(cgidata.getvalue(formvar)) + return int(cgidata.getfirst(formvar)) except (ValueError, TypeError): return defaultval confirmed = 0 # Handle changes to the list moderator password. Do this before checking # the new admin password, since the latter will force a reauthentication. - new = cgidata.getvalue('newmodpw', '').strip() - confirm = cgidata.getvalue('confirmmodpw', '').strip() + new = cgidata.getfirst('newmodpw', '').strip() + confirm = cgidata.getfirst('confirmmodpw', '').strip() if new or confirm: if new == confirm: mlist.mod_password = sha_new(new).hexdigest() @@ -1402,8 +1402,8 @@ def change_options(mlist, category, subcat, cgidata, doc): doc.addError(_('Moderator passwords did not match')) # Handle changes to the list poster password. Do this before checking # the new admin password, since the latter will force a reauthentication. - new = cgidata.getvalue('newpostpw', '').strip() - confirm = cgidata.getvalue('confirmpostpw', '').strip() + new = cgidata.getfirst('newpostpw', '').strip() + confirm = cgidata.getfirst('confirmpostpw', '').strip() if new or confirm: if new == confirm: mlist.post_password = sha_new(new).hexdigest() @@ -1412,8 +1412,8 @@ def change_options(mlist, category, subcat, cgidata, doc): else: doc.addError(_('Poster passwords did not match')) # Handle changes to the list administrator password - new = cgidata.getvalue('newpw', '').strip() - confirm = cgidata.getvalue('confirmpw', '').strip() + new = cgidata.getfirst('newpw', '').strip() + confirm = cgidata.getfirst('confirmpw', '').strip() if new or confirm: if new == confirm: mlist.password = sha_new(new).hexdigest() @@ -1429,8 +1429,8 @@ def change_options(mlist, category, subcat, cgidata, doc): gui.handleForm(mlist, category, subcat, cgidata, doc) # mass subscription, removal processing for members category subscribers = '' - subscribers += cgidata.getvalue('subscribees', '') - subscribers += cgidata.getvalue('subscribees_upload', '') + subscribers += cgidata.getfirst('subscribees', '') + subscribers += cgidata.getfirst('subscribees_upload', '') if subscribers: entries = filter(None, [n.strip() for n in subscribers.splitlines()]) send_welcome_msg = safeint('send_welcome_msg_to_this_batch', @@ -1439,7 +1439,7 @@ def change_options(mlist, category, subcat, cgidata, doc): mlist.admin_notify_mchanges) # Default is to subscribe subscribe_or_invite = safeint('subscribe_or_invite', 0) - invitation = cgidata.getvalue('invitation', '') + invitation = cgidata.getfirst('invitation', '') digest = mlist.digest_is_default if not mlist.digestable: digest = 0 @@ -1540,8 +1540,8 @@ def change_options(mlist, category, subcat, cgidata, doc): doc.AddItem('

') # Address Changes if cgidata.has_key('change_from'): - change_from = cgidata.getvalue('change_from', '') - change_to = cgidata.getvalue('change_to', '') + change_from = cgidata.getfirst('change_from', '') + change_to = cgidata.getfirst('change_to', '') schange_from = Utils.websafe(change_from) schange_to = Utils.websafe(change_to) success = False @@ -1585,7 +1585,7 @@ def change_options(mlist, category, subcat, cgidata, doc): """)) subject = _('%(list_name)s address change notice.') i18n.set_translation(otrans) - if success and cgidata.getvalue('notice_old', '') == 'yes': + if success and cgidata.getfirst('notice_old', '') == 'yes': # Send notice to old address. msg = Message.UserNotification(change_from, mlist.GetOwnerEmail(), @@ -1595,7 +1595,7 @@ def change_options(mlist, category, subcat, cgidata, doc): ) msg.send(mlist) doc.AddItem(Header(3, _('Notification sent to %(schange_from)s.'))) - if success and cgidata.getvalue('notice_new', '') == 'yes': + if success and cgidata.getfirst('notice_new', '') == 'yes': # Send notice to new address. msg = Message.UserNotification(change_to, mlist.GetOwnerEmail(), @@ -1648,16 +1648,16 @@ def change_options(mlist, category, subcat, cgidata, doc): # BAW: Hmm... pass - newname = cgidata.getvalue(quser+'_realname', '') + newname = cgidata.getfirst(quser+'_realname', '') newname = Utils.canonstr(newname, mlist.preferred_language) mlist.setMemberName(user, newname) - newlang = cgidata.getvalue(quser+'_language') + newlang = cgidata.getfirst(quser+'_language') oldlang = mlist.getMemberLanguage(user) if Utils.IsLanguage(newlang) and newlang <> oldlang: mlist.setMemberLanguage(user, newlang) - moderate = not not cgidata.getvalue(quser+'_mod') + moderate = not not cgidata.getfirst(quser+'_mod') mlist.setMemberOption(user, mm_cfg.Moderate, moderate) # Set the `nomail' flag, but only if the user isn't already -- cgit v1.2.3