Mailman vulnerability

Martin Marques martin at bugs.unl.edu.ar
Wed Nov 8 13:22:06 UTC 2006


On Wed, 8 Nov 2006, Jesse Keating wrote:

> On Wednesday 08 November 2006 06:45, Martin Marques wrote:
>> Would you people like to see the patches first or do I send the src.rpm?
>
> Either way.  We now manage FC-4 in CVS so adding just a patch to generate a
> updates-testing rpm is easy enough.

Excelent, because this one is giving me a hard time (attached file). I get 
this error when trying to build the rpm:

Patch #9 (mailman-2.1-CVE-2006-3636.patch):
+ patch -p1 -b --suffix .CVE-2006-3636 -s
9 out of 9 hunks FAILED -- saving rejects to file 
Mailman/Cgi/edithtml.py.rej
error: Bad exit status from /var/tmp/rpm-tmp.59741 (%prep)


--
  21:50:04 up 2 days,  9:07,  0 users,  load average: 0.92, 0.37, 0.18
---------------------------------------------------------
Lic. Martín Marqués         |   SELECT 'mmarques' ||
Centro de Telemática        |       '@' || 'unl.edu.ar';
Universidad Nacional        |   DBA, Programador,
     del Litoral             |   Administrador
---------------------------------------------------------
-------------- next part --------------
--- mailman-2.1.8.orig/Mailman/Cgi/admindb.py	2005-12-30 15:50:07.000000000 -0300
+++ Mailman/Cgi/admindb.py	2006-11-08 08:42:11.000000000 -0300
@@ -313,7 +313,7 @@
                      ' ' + _('Permanently ban from this list')
         # While the address may be a unicode, it must be ascii
         paddr = addr.encode('us-ascii', 'replace')
-        table.AddRow(['%s<br><em>%s</em>' % (paddr, fullname),
+        table.AddRow(['%s<br><em>%s</em>' % (paddr, Utils.websafe(fullname)),
                       radio,
                       TextBox('comment-%d' % id, size=40)
                       ])
@@ -357,8 +357,8 @@
             mlist.HandleRequest(id, mm_cfg.DISCARD)
             continue
         num += 1
-        table.AddRow(['%s<br><em>%s</em>' % (addr, fullname),
+        table.AddRow(['%s<br><em>%s</em>' % (addr, Utils.websafe(fullname)),
                       RadioButtonArray(id, (_('Defer'),
                                             _('Approve'),
                                             _('Reject'),

--- mailman-2.1.8.orig/Mailman/Cgi/create.py	2005-12-30 15:50:07.000000000 -0300
+++ Mailman/Cgi/create.py	2006-11-08 08:56:01.000000000 -0300
@@ -190,15 +190,24 @@
                 mlist.Create(listname, owner, pw, langs, emailhost)
             finally:
                 os.umask(oldmask)
-        except Errors.EmailAddressError, s:
+        except Errors.EmailAddressError, e:
+            if e.args:
+                s = Utils.websafe(e.args[0])
+            else:
+                s = Utils.websafe(owner)
             request_creation(doc, cgidata,
                              _('Bad owner email address: %(s)s'))
             return
         except Errors.MMListAlreadyExistsError:
+            # MAS: List already exists so we don't need to websafe it.
             request_creation(doc, cgidata,
                              _('List already exists: %(listname)s'))
             return
-        except Errors.BadListNameError, s:
+        except Errors.BadListNameError, e:
+            if e.args:
+                s = Utils.websafe(e.args[0])
+            else:
+                s = Utils.websafe(listname)
             request_creation(doc, cgidata,
                              _('Illegal list name: %(s)s'))
             return
@@ -321,15 +330,17 @@
     ftable.AddRow([Center(Italic(_('List Identity')))])
     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, colspan=2)
 
-    safelistname = Utils.websafe(cgidata.getvalue('listname', ''))
+    listname = cgidata.getvalue('listname', '')
+    # MAS: Don't websafe twice.  TextBox does it.
     ftable.AddRow([Label(_('Name of list:')),
-                   TextBox('listname', safelistname)])
+                   TextBox('listname', listname)])
     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)
 
-    safeowner = Utils.websafe(cgidata.getvalue('owner', ''))
+    owner = cgidata.getvalue('owner', '')
+    # MAS: Don't websafe twice.  TextBox does it.
     ftable.AddRow([Label(_('Initial list owner address:')),
-                   TextBox('owner', safeowner)])
+                   TextBox('owner', owner)])
     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
     ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)

--- mailman-2.1.8.orig/Mailman/Cgi/options.py	2005-12-02 22:07:13.000000000 -0300
+++ Mailman/Cgi/options.py	2006-11-08 08:58:00.000000000 -0300
@@ -702,8 +702,8 @@
 
     fullname = Utils.uncanonstr(mlist.getMemberName(user), userlang)
     if fullname:
-        presentable_user += ', %s' % fullname
+        presentable_user += ', %s' % Utils.websafe(fullname)
 
     # Do replacements
     replacements = mlist.GetStandardReplacements(userlang)

--- mailman-2.1.8.orig/Mailman/Cgi/edithtml.py	2006-01-09 04:06:52.000000000 -0300
+++ Mailman/Cgi/edithtml.py	2006-11-08 08:59:50.000000000 -0300
@@ -143,8 +143,9 @@
     doc.AddItem('<p>')
     doc.AddItem('<hr>')
     form = Form(mlist.GetScriptURL('edithtml') + '/' + template_name)
-    text = Utils.websafe(Utils.maketext(template_name, raw=1, mlist=mlist))
+    text = Utils.maketext(template_name, raw=1, mlist=mlist)
+    # MAS: Don't websafe twice.  TextArea does it.
     form.AddItem(TextArea('html_code', text, rows=40, cols=75))
     form.AddItem('<p>' + _('When you are done making changes...'))
     form.AddItem(SubmitButton('submit', _('Submit Changes')))
--- mailman-2.1.8.orig/Mailman/Cgi/admin.py	2005-12-30 15:50:07.000000000 -0300
+++ Mailman/Cgi/admin.py	2006-11-08 09:04:05.000000000 -0300
@@ -1318,6 +1318,7 @@
         # we display.  Try uploading a file with 10k names -- it takes a while
         # to render the status page.
         for entry in entries:
+            safeentry = Utils.websafe(entry)
             fullname, address = parseaddr(entry)
             # Canonicalize the full name
             fullname = Utils.canonstr(fullname, mlist.preferred_language)
@@ -1335,20 +1336,20 @@
                                             send_admin_notif, invitation,
                                             whence='admin mass sub')
             except Errors.MMAlreadyAMember:
-                subscribe_errors.append((entry, _('Already a member')))
+                subscribe_errors.append((safeentry, _('Already a member')))
             except Errors.MMBadEmailError:
                 if userdesc.address == '':
                     subscribe_errors.append((_('<blank line>'),
                                              _('Bad/Invalid email address')))
                 else:
-                    subscribe_errors.append((entry,
+                    subscribe_errors.append((safeentry,
                                              _('Bad/Invalid email address')))
             except Errors.MMHostileAddress:
                 subscribe_errors.append(
-                    (entry, _('Hostile address (illegal characters)')))
+                    (safeentry, _('Hostile address (illegal characters)')))
             except Errors.MembershipIsBanned, pattern:
                 subscribe_errors.append(
-                    (entry, _('Banned address (matched %(pattern)s)')))
+                    (safeentry, _('Banned address (matched %(pattern)s)')))
             else:
                 member = Utils.uncanonstr(formataddr((fullname, address)))
                 subscribe_success.append(Utils.websafe(member))
@@ -1388,10 +1389,10 @@
                     addr, whence='admin mass unsub',
                     admin_notif=send_unsub_notifications,
                     userack=userack)
-                unsubscribe_success.append(addr)
+                unsubscribe_success.append(Utils.websafe(addr))
             except Errors.NotAMemberError:
-                unsubscribe_errors.append(addr)
+                unsubscribe_errors.append(Utils.websafe(addr))
         if unsubscribe_success:
             doc.AddItem(Header(5, _('Successfully Unsubscribed:')))
             doc.AddItem(UnorderedList(*unsubscribe_success))
--- mailman-2.1.8.orig/Mailman/Utils.py	2006-03-18 14:23:04.000000000 -0300
+++ Mailman/Utils.py	2006-11-08 09:05:10.000000000 -0300
@@ -204,8 +204,8 @@
 _badchars = re.compile(r'[][()<>|;^,\000-\037\177-\377]')
 
 def ValidateEmail(s):
-    """Verify that the an email address isn't grossly evil."""
+    """Verify that an email address isn't grossly evil."""
     # Pretty minimal, cheesy check.  We could do better...
     if not s or s.count(' ') > 0:
         raise Errors.MMBadEmailError
--- mailman-2.1.8.orig/Mailman/htmlformat.py	2005-08-26 22:40:15.000000000 -0300
+++ Mailman/htmlformat.py	2006-11-08 09:08:00.000000000 -0300
@@ -448,7 +448,11 @@
 
 class TextBox(InputObj):
     def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH):
-        InputObj.__init__(self, name, "TEXT", value, checked=0, size=size)
+        if isinstance(value, str):
+            safevalue = Utils.websafe(value)
+        else:
+            safevalue = value
+        InputObj.__init__(self, name, "TEXT", safevalue, checked=0, size=size)
 
 class Hidden(InputObj):
     def __init__(self, name, value=''):
@@ -457,9 +461,13 @@
 class TextArea:
     def __init__(self, name, text='', rows=None, cols=None, wrap='soft',
                  readonly=0):
+        if isinstance(text, str):
+            safetext = Utils.websafe(text)
+        else:
+            safetext = text
         self.name = name
-        self.text = text
+        self.text = safetext
         self.rows = rows
         self.cols = cols
         self.wrap = wrap
--- mailman-2.1.8.orig/Mailman/Gui/General.py	2006-03-23 07:51:25.000000000 -0300
+++ Mailman/Gui/General.py	2006-11-08 09:09:37.000000000 -0300
@@ -439,14 +439,14 @@
             GUIBase._setValue(self, mlist, property, val, doc)
 
     def _escape(self, property, value):
-        # The 'info' property allows HTML, but lets sanitize it to avoid XSS
+        # The 'info' property allows HTML, but let's sanitize it to avoid XSS
         # exploits.  Everything else should be fully escaped.
         if property <> 'info':
             return GUIBase._escape(self, property, value)
         # Sanitize <script> and </script> tags but nothing else.  Not the best
         # solution, but expedient.
-        return re.sub(r'<([/]?script.*?)>', r'<\1>', value)
+        return re.sub(r'(?i)<([/]?script.*?)>', r'<\1>', value)
 
     def _postValidate(self, mlist, doc):
         if not mlist.reply_to_address.strip() and \
--- mailman-2.1.8.orig/Mailman/HTMLFormatter.py	2005-08-26 22:40:15.000000000 -0300
+++ Mailman/HTMLFormatter.py	2006-11-08 09:10:56.000000000 -0300
@@ -332,9 +332,13 @@
         return '</FORM>'
 
     def FormatBox(self, name, size=20, value=''):
+        if isinstance(value, str):
+            safevalue = Utils.websafe(value)
+        else:
+            safevalue = value
         return '<INPUT type="Text" name="%s" size="%d" value="%s">' % (
-            name, size, value)
+            name, size, safevalue)
 
     def FormatSecureBox(self, name):
         return '<INPUT type="Password" name="%s" size="15">' % name


More information about the fedora-legacy-list mailing list