Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 142699 Details for
Bug 208710
net-mail/mailman < 2.1.9-r3 XSS issues (CVE-2008-0564)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
mailman-2.1.9-fix-XSS.patch
mailman-2.1.9-fix-XSS.patch (text/plain), 11.02 KB, created by
Jonathan Smith (RETIRED)
on 2008-02-05 08:54:00 UTC
(
hide
)
Description:
mailman-2.1.9-fix-XSS.patch
Filename:
MIME Type:
Creator:
Jonathan Smith (RETIRED)
Created:
2008-02-05 08:54:00 UTC
Size:
11.02 KB
patch
obsolete
>=== modified file 'Mailman/Cgi/edithtml.py' >--- Mailman/Cgi/edithtml.py 2006-08-30 14:54:22 +0000 >+++ Mailman/Cgi/edithtml.py 2007-12-04 19:52:18 +0000 >@@ -1,4 +1,4 @@ >-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc. >+# Copyright (C) 1998-2007 by the Free Software Foundation, Inc. > # > # This program is free software; you can redistribute it and/or > # modify it under the terms of the GNU General Public License >@@ -159,7 +159,20 @@ > doc.AddItem('<hr>') > return > code = cgi_info['html_code'].value >- code = re.sub(r'<([/]?script.*?)>', r'<\1>', code) >+ if Utils.suspiciousHTML(code): >+ doc.AddItem(Header(3, >+ _("""The page you saved contains suspicious HTML that could >+potentially expose your users to cross-site scripting attacks. This change >+has therefore been rejected. If you still want to make these changes, you >+must have shell access to your Mailman server. >+ """))) >+ doc.AddItem(_('See ')) >+ doc.AddItem(Link( >+'http://www.python.org/cgi-bin/faqw-mm.py?req=show&file=faq04.048.htp', >+ _('FAQ 4.48.'))) >+ doc.AddItem(Header(3,_("Page Unchanged."))) >+ doc.AddItem('<hr>') >+ return > langdir = os.path.join(mlist.fullpath(), mlist.preferred_language) > # Make sure the directory exists > omask = os.umask(0) > >=== modified file 'Mailman/Gui/General.py' >--- Mailman/Gui/General.py 2006-08-30 14:54:22 +0000 >+++ Mailman/Gui/General.py 2007-12-04 19:52:18 +0000 >@@ -1,4 +1,4 @@ >-# Copyright (C) 2001-2006 by the Free Software Foundation, Inc. >+# Copyright (C) 2001-2007 by the Free Software Foundation, Inc. > # > # This program is free software; you can redistribute it and/or > # modify it under the terms of the GNU General Public License >@@ -436,17 +442,21 @@ > # Convert any html entities to Unicode > mlist.subject_prefix = Utils.canonstr( > val, mlist.preferred_language) >+ elif property == 'info': >+ if val <> mlist.info: >+ if Utils.suspiciousHTML(val): >+ doc.addError(_("""The <b>info</b> attribute you saved >+contains suspicious HTML that could potentially expose your users to cross-site >+scripting attacks. This change has therefore been rejected. If you still want >+to make these changes, you must have shell access to your Mailman server. >+This change can be made with bin/withlist or with bin/config_list by setting >+mlist.info. >+ """)) >+ else: >+ mlist.info = val > else: > GUIBase._setValue(self, mlist, property, val, doc) > >- def _escape(self, property, value): >- # 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'(?i)<([/]?script.*?)>', r'<\1>', value) > > def _postValidate(self, mlist, doc): > if not mlist.reply_to_address.strip() and \ > >=== modified file 'Mailman/Gui/GUIBase.py' >--- Mailman/Gui/GUIBase.py 2005-08-27 01:40:17 +0000 >+++ Mailman/Gui/GUIBase.py 2007-11-18 20:01:26 +0000 >@@ -1,4 +1,4 @@ >-# Copyright (C) 2002-2004 by the Free Software Foundation, Inc. >+# Copyright (C) 2002-2007 by the Free Software Foundation, Inc. > # > # This program is free software; you can redistribute it and/or > # modify it under the terms of the GNU General Public License >@@ -12,7 +12,8 @@ > # > # You should have received a copy of the GNU General Public License > # along with this program; if not, write to the Free Software >-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. >+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, >+# USA. > > """Base class for all web GUI components.""" > >@@ -122,10 +127,6 @@ > # Validate all the attributes for this category > pass > >- def _escape(self, property, value): >- value = value.replace('<', '<') >- return value >- > def handleForm(self, mlist, category, subcat, cgidata, doc): > for item in self.GetConfigInfo(mlist, category, subcat): > # Skip descriptions and legacy non-attributes >@@ -144,10 +145,9 @@ > elif not cgidata.has_key(property): > continue > elif isinstance(cgidata[property], ListType): >- val = [self._escape(property, x.value) >- for x in cgidata[property]] >+ val = [x.value for x in cgidata[property]] > else: >- val = self._escape(property, cgidata[property].value) >+ val = cgidata[property].value > # Coerce the value to the expected type, raising exceptions if the > # value is invalid. > try: > >=== modified file 'Mailman/Utils.py' >--- Mailman/Utils.py 2007-11-25 08:04:30 +0000 >+++ Mailman/Utils.py 2007-12-04 19:52:18 +0000 >@@ -876,3 +876,154 @@ > except (LookupError, UnicodeError, ValueError, HeaderParseError): > # possibly charset problem. return with undecoded string in one line. > return EMPTYSTRING.join(s.splitlines()) >+ >+ >+# Patterns and functions to flag possible XSS attacks in HTML. >+# This list is compiled from information at http://ha.ckers.org/xss.html, >+# http://www.quirksmode.org/js/events_compinfo.html, >+# http://www.htmlref.com/reference/appa/events1.htm, >+# http://lxr.mozilla.org/mozilla/source/content/events/src/nsDOMEvent.cpp#59, >+# http://www.w3.org/TR/DOM-Level-2-Events/events.html and >+# http://www.xulplanet.com/references/elemref/ref_EventHandlers.html >+# Many thanks are due to Moritz Naumann for his assistance with this. >+_badwords = [ >+ '<i?frame', >+ '<link', >+ '<meta', >+ '<script', >+ r'(?:^|\W)j(?:ava)?script(?:\W|$)', >+ r'(?:^|\W)vbs(?:cript)?(?:\W|$)', >+ r'(?:^|\W)domactivate(?:\W|$)', >+ r'(?:^|\W)domattrmodified(?:\W|$)', >+ r'(?:^|\W)domcharacterdatamodified(?:\W|$)', >+ r'(?:^|\W)domfocus(?:in|out)(?:\W|$)', >+ r'(?:^|\W)dommenuitem(?:in)?active(?:\W|$)', >+ r'(?:^|\W)dommousescroll(?:\W|$)', >+ r'(?:^|\W)domnodeinserted(?:intodocument)?(?:\W|$)', >+ r'(?:^|\W)domnoderemoved(?:fromdocument)?(?:\W|$)', >+ r'(?:^|\W)domsubtreemodified(?:\W|$)', >+ r'(?:^|\W)fscommand(?:\W|$)', >+ r'(?:^|\W)onabort(?:\W|$)', >+ r'(?:^|\W)on(?:de)?activate(?:\W|$)', >+ r'(?:^|\W)on(?:after|before)print(?:\W|$)', >+ r'(?:^|\W)on(?:after|before)update(?:\W|$)', >+ r'(?:^|\W)onbefore(?:(?:de)?activate|copy|cut|editfocus|paste)(?:\W|$)', >+ r'(?:^|\W)onbeforeunload(?:\W|$)', >+ r'(?:^|\W)onbegin(?:\W|$)', >+ r'(?:^|\W)onblur(?:\W|$)', >+ r'(?:^|\W)onbounce(?:\W|$)', >+ r'(?:^|\W)onbroadcast(?:\W|$)', >+ r'(?:^|\W)on(?:cell)?change(?:\W|$)', >+ r'(?:^|\W)oncheckboxstatechange(?:\W|$)', >+ r'(?:^|\W)on(?:dbl)?click(?:\W|$)', >+ r'(?:^|\W)onclose(?:\W|$)', >+ r'(?:^|\W)oncommand(?:update)?(?:\W|$)', >+ r'(?:^|\W)oncomposition(?:end|start)(?:\W|$)', >+ r'(?:^|\W)oncontextmenu(?:\W|$)', >+ r'(?:^|\W)oncontrolselect(?:\W|$)', >+ r'(?:^|\W)oncopy(?:\W|$)', >+ r'(?:^|\W)oncut(?:\W|$)', >+ r'(?:^|\W)ondataavailable(?:\W|$)', >+ r'(?:^|\W)ondataset(?:changed|complete)(?:\W|$)', >+ r'(?:^|\W)ondrag(?:drop|end|enter|exit|gesture|leave|over)?(?:\W|$)', >+ r'(?:^|\W)ondragstart(?:\W|$)', >+ r'(?:^|\W)ondrop(?:\W|$)', >+ r'(?:^|\W)onend(?:\W|$)', >+ r'(?:^|\W)onerror(?:update)?(?:\W|$)', >+ r'(?:^|\W)onfilterchange(?:\W|$)', >+ r'(?:^|\W)onfinish(?:\W|$)', >+ r'(?:^|\W)onfocus(?:in|out)?(?:\W|$)', >+ r'(?:^|\W)onhelp(?:\W|$)', >+ r'(?:^|\W)oninput(?:\W|$)', >+ r'(?:^|\W)onkey(?:up|down|press)(?:\W|$)', >+ r'(?:^|\W)onlayoutcomplete(?:\W|$)', >+ r'(?:^|\W)on(?:un)?load(?:\W|$)', >+ r'(?:^|\W)onlosecapture(?:\W|$)', >+ r'(?:^|\W)onmedia(?:complete|error)(?:\W|$)', >+ r'(?:^|\W)onmouse(?:down|enter|leave|move|out|over|up|wheel)(?:\W|$)', >+ r'(?:^|\W)onmove(?:end|start)?(?:\W|$)', >+ r'(?:^|\W)on(?:off|on)line(?:\W|$)', >+ r'(?:^|\W)onoutofsync(?:\W|$)', >+ r'(?:^|\W)onoverflow(?:changed)?(?:\W|$)', >+ r'(?:^|\W)onpage(?:hide|show)(?:\W|$)', >+ r'(?:^|\W)onpaint(?:\W|$)', >+ r'(?:^|\W)onpaste(?:\W|$)', >+ r'(?:^|\W)onpause(?:\W|$)', >+ r'(?:^|\W)onpopup(?:hidden|hiding|showing|shown)(?:\W|$)', >+ r'(?:^|\W)onprogress(?:\W|$)', >+ r'(?:^|\W)onpropertychange(?:\W|$)', >+ r'(?:^|\W)onradiostatechange(?:\W|$)', >+ r'(?:^|\W)onreadystatechange(?:\W|$)', >+ r'(?:^|\W)onrepeat(?:\W|$)', >+ r'(?:^|\W)onreset(?:\W|$)', >+ r'(?:^|\W)onresize(?:end|start)?(?:\W|$)', >+ r'(?:^|\W)onresume(?:\W|$)', >+ r'(?:^|\W)onreverse(?:\W|$)', >+ r'(?:^|\W)onrow(?:delete|enter|exit|inserted)(?:\W|$)', >+ r'(?:^|\W)onrows(?:delete|enter|inserted)(?:\W|$)', >+ r'(?:^|\W)onscroll(?:\W|$)', >+ r'(?:^|\W)onseek(?:\W|$)', >+ r'(?:^|\W)onselect(?:start)?(?:\W|$)', >+ r'(?:^|\W)onselectionchange(?:\W|$)', >+ r'(?:^|\W)onstart(?:\W|$)', >+ r'(?:^|\W)onstop(?:\W|$)', >+ r'(?:^|\W)onsubmit(?:\W|$)', >+ r'(?:^|\W)onsync(?:from|to)preference(?:\W|$)', >+ r'(?:^|\W)onsyncrestored(?:\W|$)', >+ r'(?:^|\W)ontext(?:\W|$)', >+ r'(?:^|\W)ontimeerror(?:\W|$)', >+ r'(?:^|\W)ontrackchange(?:\W|$)', >+ r'(?:^|\W)onunderflow(?:\W|$)', >+ r'(?:^|\W)onurlflip(?:\W|$)', >+ r'(?:^|\W)seeksegmenttime(?:\W|$)', >+ r'(?:^|\W)svgabort(?:\W|$)', >+ r'(?:^|\W)svgerror(?:\W|$)', >+ r'(?:^|\W)svgload(?:\W|$)', >+ r'(?:^|\W)svgresize(?:\W|$)', >+ r'(?:^|\W)svgscroll(?:\W|$)', >+ r'(?:^|\W)svgunload(?:\W|$)', >+ r'(?:^|\W)svgzoom(?:\W|$)', >+ ] >+ >+ >+# This is the actual re to look for the above patterns >+_badhtml = re.compile('|'.join(_badwords), re.IGNORECASE) >+# This is used to filter non-printable us-ascii characters, some of which >+# can be used to break words to avoid recognition. >+_filterchars = re.compile('[\000-\011\013\014\016-\037\177-\237]') >+# This is used to recognize '&#' and '%xx' strings for _translate which >+# translates them to characters >+_encodedchars = re.compile('(&#[0-9]+;?)|(&#x[0-9a-f]+;?)|(%[0-9a-f]{2})', >+ re.IGNORECASE) >+ >+ >+def _translate(mo): >+ """Translate &#... and %xx encodings into the encoded character.""" >+ match = mo.group().lower().strip('&#;') >+ try: >+ if match.startswith('x') or match.startswith('%'): >+ val = int(match[1:], 16) >+ else: >+ val = int(match, 10) >+ except ValueError: >+ return '' >+ if val < 256: >+ return chr(val) >+ else: >+ return '' >+ >+ >+def suspiciousHTML(html): >+ """Check HTML string for various tags, script language names and >+ 'onxxx' actions that can be used in XSS attacks. >+ Currently, this a very simple minded test. It just looks for >+ patterns without analyzing context. Thus, it potentially flags lots >+ of benign stuff. >+ Returns True if anything suspicious found, False otherwise. >+ """ >+ >+ if _badhtml.search(_filterchars.sub( >+ '', _encodedchars.sub(_translate, html))): >+ return True >+ else: >+ return False >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 208710
: 142699