Package: release.debian.org Severity: normal Tags: buster User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-Cc: car...@debian.org
Hi SRM, There was another CVE fixed after the last update currently in buster-pu for mailman which similarly we think does not warrant a DSA. I have prepared a followup for this one as well: https://security-tracker.debian.org/tracker/CVE-2021-44227 I'm attaching both debdiffs, once against the base version currently in buster (1:2.1.29-1+deb10u1, note that htere was as well a DSA for mailman, 1:2.1.29-1+deb10u2) and once only against the current version which sits in buster-proposed-updates. Regards, Salvatore
diff -Nru mailman-2.1.29/debian/changelog mailman-2.1.29/debian/changelog --- mailman-2.1.29/debian/changelog 2021-11-20 15:17:30.000000000 +0100 +++ mailman-2.1.29/debian/changelog 2021-12-12 10:42:54.000000000 +0100 @@ -1,3 +1,11 @@ +mailman (1:2.1.29-1+deb10u4) buster; urgency=medium + + * Non-maintainer upload by the Security Team. + * Fix potential CSRF attack against a list admin from a list member or + moderator (CVE-2021-44227) + + -- Salvatore Bonaccorso <car...@debian.org> Sun, 12 Dec 2021 10:42:54 +0100 + mailman (1:2.1.29-1+deb10u3) buster; urgency=medium * Non-maintainer upload by the Security Team. diff -Nru mailman-2.1.29/debian/patches/CVE-2021-44227.patch mailman-2.1.29/debian/patches/CVE-2021-44227.patch --- mailman-2.1.29/debian/patches/CVE-2021-44227.patch 1970-01-01 01:00:00.000000000 +0100 +++ mailman-2.1.29/debian/patches/CVE-2021-44227.patch 2021-12-12 10:42:54.000000000 +0100 @@ -0,0 +1,82 @@ +Description: Fix potential CSRF attack against a list admin from a list member or moderator +Origin: upstream, https://bazaar.launchpad.net/~mailman-coders/mailman/2.1/diff/1882 +Bug: https://launchpad.net/bugs/1952384 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-44227 +Forwarded: not-needed +Last-Update: 2021-12-12 + +=== modified file 'Mailman/CSRFcheck.py' +--- a/Mailman/CSRFcheck.py ++++ b/Mailman/CSRFcheck.py +@@ -55,7 +55,7 @@ def csrf_token(mlist, contexts, user=Non + token = binascii.hexlify(marshal.dumps((issued, keymac))) + return token + +-def csrf_check(mlist, token, options_user=None): ++def csrf_check(mlist, token, cgi_user=None): + """ check token by mailman cookie validation algorithm """ + try: + issued, keymac = marshal.loads(binascii.unhexlify(token)) +@@ -67,12 +67,25 @@ def csrf_check(mlist, token, options_use + key, user = key.split('+', 1) + else: + user = None ++ # Don't allow unprivileged tokens for admin or admindb. ++ if cgi_user == 'admin': ++ if key not in ('admin', 'site'): ++ syslog('mischief', ++ 'admin form submitted with CSRF token issued for %s.', ++ key + '+' + user if user else key) ++ return False ++ elif cgi_user == 'admindb': ++ if key not in ('moderator', 'admin', 'site'): ++ syslog('mischief', ++ 'admindb form submitted with CSRF token issued for %s.', ++ key + '+' + user if user else key) ++ return False + if user: + # This is for CVE-2021-42097. The token is a user token because + # of the fix for CVE-2021-42096 but it must match the user for + # whom the options page is requested. + raw_user = UnobscureEmail(urllib.unquote(user)) +- if options_user and options_user != raw_user: ++ if cgi_user and cgi_user != raw_user: + syslog('mischief', + 'Form for user %s submitted with CSRF token ' + 'issued for %s.', +--- a/Mailman/Cgi/admin.py ++++ b/Mailman/Cgi/admin.py +@@ -107,7 +107,8 @@ def main(): + 'legend'] + params = cgidata.keys() + if set(params) - set(safe_params): +- csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token')) ++ csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'), ++ 'admin') + else: + csrf_checked = True + # if password is present, void cookie to force password authentication. +--- a/Mailman/Cgi/admindb.py ++++ b/Mailman/Cgi/admindb.py +@@ -144,7 +144,8 @@ def main(): + safe_params = ['adminpw', 'admlogin', 'msgid', 'sender', 'details'] + params = cgidata.keys() + if set(params) - set(safe_params): +- csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token')) ++ csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'), ++ 'admindb') + else: + csrf_checked = True + # if password is present, void cookie to force password authentication. +--- a/Mailman/Cgi/edithtml.py ++++ b/Mailman/Cgi/edithtml.py +@@ -111,7 +111,8 @@ def main(): + safe_params = ['VARHELP', 'adminpw', 'admlogin'] + params = cgidata.keys() + if set(params) - set(safe_params): +- csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token')) ++ csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'), ++ 'admin') + else: + csrf_checked = True + # if password is present, void cookie to force password authentication. diff -Nru mailman-2.1.29/debian/patches/series mailman-2.1.29/debian/patches/series --- mailman-2.1.29/debian/patches/series 2021-11-20 15:17:30.000000000 +0100 +++ mailman-2.1.29/debian/patches/series 2021-12-12 10:42:54.000000000 +0100 @@ -15,3 +15,4 @@ 1873-CVE-2021-42096_CVE-2021-42097.patch CVE-2021-43331.patch CVE-2021-43332.patch +CVE-2021-44227.patch
diff -Nru mailman-2.1.29/debian/changelog mailman-2.1.29/debian/changelog --- mailman-2.1.29/debian/changelog 2020-04-24 16:27:05.000000000 +0200 +++ mailman-2.1.29/debian/changelog 2021-12-12 10:42:54.000000000 +0100 @@ -1,3 +1,31 @@ +mailman (1:2.1.29-1+deb10u4) buster; urgency=medium + + * Non-maintainer upload by the Security Team. + * Fix potential CSRF attack against a list admin from a list member or + moderator (CVE-2021-44227) + + -- Salvatore Bonaccorso <car...@debian.org> Sun, 12 Dec 2021 10:42:54 +0100 + +mailman (1:2.1.29-1+deb10u3) buster; urgency=medium + + * Non-maintainer upload by the Security Team. + * Potential XSS attack via the user options page (CVE-2021-43331) + (Closes: #1000367) + * A list moderator can crack the list admin password encrypted in a CSRF + token (CVE-2021-43332) (Closes: #1000367) + + -- Salvatore Bonaccorso <car...@debian.org> Sat, 20 Nov 2021 15:17:30 +0100 + +mailman (1:2.1.29-1+deb10u2) buster-security; urgency=high + + * Non-maintainer upload by the Security Team. + * Fixed options login content injection vulnerability (CVE-2020-12108) + * Fixed content injection vulnerability via the private login page + (CVE-2020-15011) + * Fix remote privilege escalation (CVE-2021-42096, CVE-2021-42097) + + -- Salvatore Bonaccorso <car...@debian.org> Fri, 22 Oct 2021 14:32:39 +0200 + mailman (1:2.1.29-1+deb10u1) buster-security; urgency=high * Upload to buster for security issue. diff -Nru mailman-2.1.29/debian/patches/1844-CVE-2020-12108.patch mailman-2.1.29/debian/patches/1844-CVE-2020-12108.patch --- mailman-2.1.29/debian/patches/1844-CVE-2020-12108.patch 1970-01-01 01:00:00.000000000 +0100 +++ mailman-2.1.29/debian/patches/1844-CVE-2020-12108.patch 2021-12-12 10:42:54.000000000 +0100 @@ -0,0 +1,17 @@ +Description: Fixed options login content injection vulnerability +Origin: upstream, https://bazaar.launchpad.net/~mailman-coders/mailman/2.1/revision/1844 +Bug: https://bugs.launchpad.net/mailman/+bug/1873722 +Bug-Debian-security: https://security-tracker.debian.org/tracker/CVE-2020-12108 +Last-Update: 2021-10-22 + +--- a/Mailman/Cgi/options.py ++++ b/Mailman/Cgi/options.py +@@ -172,7 +172,7 @@ def main(): + try: + Utils.ValidateEmail(user) + except Errors.EmailAddressError: +- doc.addError(_('Illegal Email Address: %(safeuser)s')) ++ doc.addError(_('Illegal Email Address')) + loginpage(mlist, doc, None, language) + print doc.Format() + return diff -Nru mailman-2.1.29/debian/patches/1848-CVE-2020-15011.patch mailman-2.1.29/debian/patches/1848-CVE-2020-15011.patch --- mailman-2.1.29/debian/patches/1848-CVE-2020-15011.patch 1970-01-01 01:00:00.000000000 +0100 +++ mailman-2.1.29/debian/patches/1848-CVE-2020-15011.patch 2021-12-12 10:42:54.000000000 +0100 @@ -0,0 +1,26 @@ +Description: Fixed content injection vulnerability via the private login page +Origin: upstream, https://bazaar.launchpad.net/~mailman-coders/mailman/2.1/revision/1848 +Bug: https://launchpad.net/bugs/1877379 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-15011 +Last-Update: 2021-10-22 + +--- a/Mailman/Cgi/private.py 2019-03-06 17:48:32 +0000 ++++ b/Mailman/Cgi/private.py 2020-05-07 13:53:40 +0000 +@@ -162,13 +162,9 @@ + if mlist.isMember(username): + mlist.MailUserPassword(username) + elif username: +- # Not a member +- if mlist.private_roster == 0: +- # Public rosters +- safeuser = Utils.websafe(username) +- message = Bold(FontSize('+1', +- _('No such member: %(safeuser)s.'))).Format() +- else: ++ # Not a member. Don't report address in any case. It leads to ++ # Content injection. Just log if roster is not public. ++ if mlist.private_roster != 0: + syslog('mischief', + 'Reminder attempt of non-member w/ private rosters: %s', + username) + diff -Nru mailman-2.1.29/debian/patches/1873-CVE-2021-42096_CVE-2021-42097.patch mailman-2.1.29/debian/patches/1873-CVE-2021-42096_CVE-2021-42097.patch --- mailman-2.1.29/debian/patches/1873-CVE-2021-42096_CVE-2021-42097.patch 1970-01-01 01:00:00.000000000 +0100 +++ mailman-2.1.29/debian/patches/1873-CVE-2021-42096_CVE-2021-42097.patch 2021-12-12 10:42:54.000000000 +0100 @@ -0,0 +1,131 @@ +Description: Fix remote Privilege Escalation +Origin: upstream, https://bazaar.launchpad.net/~mailman-coders/mailman/2.1/revision/1873 +Bug: https://bugs.launchpad.net/mailman/+bug/1947639 +Bug: https://bugs.launchpad.net/mailman/+bug/1947640 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-42096 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-42097 +Last-Update: 2021-10-22 + +--- a/Mailman/CSRFcheck.py ++++ b/Mailman/CSRFcheck.py +@@ -18,11 +18,13 @@ + """ Cross-Site Request Forgery checker """ + + import time ++import urllib + import marshal + import binascii + + from Mailman import mm_cfg +-from Mailman.Utils import sha_new ++from Mailman.Logging.Syslog import syslog ++from Mailman.Utils import UnobscureEmail, sha_new + + keydict = { + 'user': mm_cfg.AuthUser, +@@ -37,6 +39,10 @@ keydict = { + def csrf_token(mlist, contexts, user=None): + """ create token by mailman cookie generation algorithm """ + ++ if user: ++ # Unmunge a munged email address. ++ user = UnobscureEmail(urllib.unquote(user)) ++ + for context in contexts: + key, secret = mlist.AuthContextInfo(context, user) + if key: +@@ -49,9 +55,8 @@ def csrf_token(mlist, contexts, user=Non + token = binascii.hexlify(marshal.dumps((issued, keymac))) + return token + +-def csrf_check(mlist, token): ++def csrf_check(mlist, token, options_user=None): + """ check token by mailman cookie validation algorithm """ +- + try: + issued, keymac = marshal.loads(binascii.unhexlify(token)) + key, received_mac = keymac.split(':', 1) +@@ -62,6 +67,17 @@ def csrf_check(mlist, token): + key, user = key.split('+', 1) + else: + user = None ++ if user: ++ # This is for CVE-2021-42097. The token is a user token because ++ # of the fix for CVE-2021-42096 but it must match the user for ++ # whom the options page is requested. ++ raw_user = UnobscureEmail(urllib.unquote(user)) ++ if options_user and options_user != raw_user: ++ syslog('mischief', ++ 'Form for user %s submitted with CSRF token ' ++ 'issued for %s.', ++ options_user, raw_user) ++ return False + context = keydict.get(key) + key, secret = mlist.AuthContextInfo(context, user) + assert key +--- a/Mailman/Cgi/options.py ++++ b/Mailman/Cgi/options.py +@@ -54,9 +54,6 @@ except NameError: + True = 1 + False = 0 + +-AUTH_CONTEXTS = (mm_cfg.AuthListAdmin, mm_cfg.AuthSiteAdmin, +- mm_cfg.AuthListModerator, mm_cfg.AuthUser) +- + + def main(): + global _ +@@ -124,15 +121,6 @@ def main(): + print doc.Format() + return + +- if set(params) - set(safe_params): +- 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.getfirst('password'): +- os.environ['HTTP_COOKIE'] = '' +- csrf_checked = True +- + # Set the language for the page. If we're coming from the listinfo cgi, + # we might have a 'language' key in the cgi data. That was an explicit + # preference to view the page in, so we should honor that here. If that's +@@ -168,6 +156,16 @@ def main(): + user = user[-1] + + # Avoid cross-site scripting attacks ++ if set(params) - set(safe_params): ++ csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'), ++ Utils.UnobscureEmail(urllib.unquote(user))) ++ else: ++ csrf_checked = True ++ # if password is present, void cookie to force password authentication. ++ if cgidata.getfirst('password'): ++ os.environ['HTTP_COOKIE'] = '' ++ csrf_checked = True ++ + safeuser = Utils.websafe(user) + try: + Utils.ValidateEmail(user) +@@ -867,8 +865,9 @@ def options_page(mlist, doc, user, cpuse + mlist.FormatButton('othersubs', + _('List my other subscriptions'))) + replacements['<mm-form-start>'] = ( ++ # Always make the CSRF token for the user. CVE-2021-42096 + mlist.FormatFormStart('options', user, mlist=mlist, +- contexts=AUTH_CONTEXTS, user=user)) ++ contexts=[mm_cfg.AuthUser], user=user)) + replacements['<mm-user>'] = user + replacements['<mm-presentable-user>'] = presentable_user + replacements['<mm-email-my-pw>'] = mlist.FormatButton( +--- a/Mailman/SecurityManager.py ++++ b/Mailman/SecurityManager.py +@@ -104,6 +104,7 @@ class SecurityManager: + if user is None: + # A bad system error + raise TypeError, 'No user supplied for AuthUser context' ++ user = Utils.UnobscureEmail(urllib.unquote(user)) + secret = self.getMemberPassword(user) + userdata = urllib.quote(Utils.ObscureEmail(user), safe='') + key += 'user+%s' % userdata diff -Nru mailman-2.1.29/debian/patches/CVE-2021-43331.patch mailman-2.1.29/debian/patches/CVE-2021-43331.patch --- mailman-2.1.29/debian/patches/CVE-2021-43331.patch 1970-01-01 01:00:00.000000000 +0100 +++ mailman-2.1.29/debian/patches/CVE-2021-43331.patch 2021-12-12 10:42:54.000000000 +0100 @@ -0,0 +1,19 @@ +Description: Potential XSS attack via the user options page +Origin: upstream, https://bugs.launchpad.net/mailman/+bug/1949401/+attachment/5540165/+files/patch_to_fix_1949401 +Bug: https://bugs.launchpad.net/mailman/+bug/1949401 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-43331 +Forwarded: not-needed +Last-Update: 2021-11-20 + +=== modified file 'Mailman/Cgi/options.py' +--- a/Mailman/Cgi/options.py ++++ b/Mailman/Cgi/options.py +@@ -342,6 +342,8 @@ def main(): + varhelp = qs[0] + if varhelp: + # Sanitize the topic name. ++ while '%' in varhelp: ++ varhelp = urllib.unquote_plus(varhelp) + varhelp = re.sub('<.*', '', varhelp) + topic_details(mlist, doc, user, cpuser, userlang, varhelp) + return diff -Nru mailman-2.1.29/debian/patches/CVE-2021-43332.patch mailman-2.1.29/debian/patches/CVE-2021-43332.patch --- mailman-2.1.29/debian/patches/CVE-2021-43332.patch 1970-01-01 01:00:00.000000000 +0100 +++ mailman-2.1.29/debian/patches/CVE-2021-43332.patch 2021-12-12 10:42:54.000000000 +0100 @@ -0,0 +1,32 @@ +Description: A list moderator can crack the list admin password encrypted in a CSRF token +Origin: upstream, https://bugs.launchpad.net/mailman/+bug/1949403/+attachment/5540558/+files/patch_to_fix_1949403 +Bug: https://bugs.launchpad.net/mailman/+bug/1949403 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-43332 +Forwarded: not-needed +Last-Update: 2021-11-20 + +=== modified file 'Mailman/CSRFcheck.py' +--- a/Mailman/CSRFcheck.py ++++ b/Mailman/CSRFcheck.py +@@ -45,7 +45,7 @@ def csrf_token(mlist, contexts, user=Non + + for context in contexts: + key, secret = mlist.AuthContextInfo(context, user) +- if key: ++ if key and secret: + break + else: + return None # not authenticated +--- a/Mailman/Cgi/admindb.py ++++ b/Mailman/Cgi/admindb.py +@@ -59,8 +59,8 @@ if mm_cfg.DISPLAY_HELD_SUMMARY_SORT_BUTT + else: + ssort = SSENDER + +-AUTH_CONTEXTS = (mm_cfg.AuthListAdmin, mm_cfg.AuthSiteAdmin, +- mm_cfg.AuthListModerator) ++AUTH_CONTEXTS = (mm_cfg.AuthListModerator, mm_cfg.AuthListAdmin, ++ mm_cfg.AuthSiteAdmin) + + + diff -Nru mailman-2.1.29/debian/patches/CVE-2021-44227.patch mailman-2.1.29/debian/patches/CVE-2021-44227.patch --- mailman-2.1.29/debian/patches/CVE-2021-44227.patch 1970-01-01 01:00:00.000000000 +0100 +++ mailman-2.1.29/debian/patches/CVE-2021-44227.patch 2021-12-12 10:42:54.000000000 +0100 @@ -0,0 +1,82 @@ +Description: Fix potential CSRF attack against a list admin from a list member or moderator +Origin: upstream, https://bazaar.launchpad.net/~mailman-coders/mailman/2.1/diff/1882 +Bug: https://launchpad.net/bugs/1952384 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-44227 +Forwarded: not-needed +Last-Update: 2021-12-12 + +=== modified file 'Mailman/CSRFcheck.py' +--- a/Mailman/CSRFcheck.py ++++ b/Mailman/CSRFcheck.py +@@ -55,7 +55,7 @@ def csrf_token(mlist, contexts, user=Non + token = binascii.hexlify(marshal.dumps((issued, keymac))) + return token + +-def csrf_check(mlist, token, options_user=None): ++def csrf_check(mlist, token, cgi_user=None): + """ check token by mailman cookie validation algorithm """ + try: + issued, keymac = marshal.loads(binascii.unhexlify(token)) +@@ -67,12 +67,25 @@ def csrf_check(mlist, token, options_use + key, user = key.split('+', 1) + else: + user = None ++ # Don't allow unprivileged tokens for admin or admindb. ++ if cgi_user == 'admin': ++ if key not in ('admin', 'site'): ++ syslog('mischief', ++ 'admin form submitted with CSRF token issued for %s.', ++ key + '+' + user if user else key) ++ return False ++ elif cgi_user == 'admindb': ++ if key not in ('moderator', 'admin', 'site'): ++ syslog('mischief', ++ 'admindb form submitted with CSRF token issued for %s.', ++ key + '+' + user if user else key) ++ return False + if user: + # This is for CVE-2021-42097. The token is a user token because + # of the fix for CVE-2021-42096 but it must match the user for + # whom the options page is requested. + raw_user = UnobscureEmail(urllib.unquote(user)) +- if options_user and options_user != raw_user: ++ if cgi_user and cgi_user != raw_user: + syslog('mischief', + 'Form for user %s submitted with CSRF token ' + 'issued for %s.', +--- a/Mailman/Cgi/admin.py ++++ b/Mailman/Cgi/admin.py +@@ -107,7 +107,8 @@ def main(): + 'legend'] + params = cgidata.keys() + if set(params) - set(safe_params): +- csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token')) ++ csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'), ++ 'admin') + else: + csrf_checked = True + # if password is present, void cookie to force password authentication. +--- a/Mailman/Cgi/admindb.py ++++ b/Mailman/Cgi/admindb.py +@@ -144,7 +144,8 @@ def main(): + safe_params = ['adminpw', 'admlogin', 'msgid', 'sender', 'details'] + params = cgidata.keys() + if set(params) - set(safe_params): +- csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token')) ++ csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'), ++ 'admindb') + else: + csrf_checked = True + # if password is present, void cookie to force password authentication. +--- a/Mailman/Cgi/edithtml.py ++++ b/Mailman/Cgi/edithtml.py +@@ -111,7 +111,8 @@ def main(): + safe_params = ['VARHELP', 'adminpw', 'admlogin'] + params = cgidata.keys() + if set(params) - set(safe_params): +- csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token')) ++ csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'), ++ 'admin') + else: + csrf_checked = True + # if password is present, void cookie to force password authentication. diff -Nru mailman-2.1.29/debian/patches/series mailman-2.1.29/debian/patches/series --- mailman-2.1.29/debian/patches/series 2020-04-24 16:27:02.000000000 +0200 +++ mailman-2.1.29/debian/patches/series 2021-12-12 10:42:54.000000000 +0100 @@ -10,3 +10,9 @@ 79_archiver_slash.patch 92_reproducible_build.patch scrubber-obj2bin.patch +1844-CVE-2020-12108.patch +1848-CVE-2020-15011.patch +1873-CVE-2021-42096_CVE-2021-42097.patch +CVE-2021-43331.patch +CVE-2021-43332.patch +CVE-2021-44227.patch