Hi Nicolas,

Could you upload that security update for Debian stable. I have updated
(and attached) that patch, to mention the CVE number as suggested by
Raphael.

Thanks,

Franklin

Nc Golde wrote:
> Hi,
> any news on this bug report? It's a bit sad to see a fix but nothing
> happening. Frank, if you need sponsoring I can sponsor your upload or
> Jonas please pick this up and upload. I don't want to hijack this,
> hence the mail but it would be nice to get this fixed.

diff --git a/debian/changelog b/debian/changelog
index 2d7ce4a..0bb8a7c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+moin (1.7.1-3+lenny5) stable-security; urgency=high
+
+  * Non-maintainer upload.
+  * Fixed XSS in theme.add_msg, CVE-2010-2487
+    (Closes: #584809)
+
+ -- Frank Lin PIAT <fp...@klabs.be>  Mon, 07 Jun 2010 06:48:00 +0200
+
 moin (1.7.1-3+lenny4) stable-security; urgency=high
 
   * Non-maintainer upload by the Security Team.
diff --git a/debian/patches/series b/debian/patches/series
index f3c6cd2..9e4916b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,4 @@ CVE-2010-0669.patch
 security_hierarchical_ACL.patch
 CVE-2010-0828.patch
 textcha.patch
+CVE-2010-2487-XSS.patch
diff --git a/debian/patches/CVE-2010-2487-XSS.patch b/debian/patches/CVE-2010-2487-XSS.patch
new file mode 100644
index 0000000..d353459
--- /dev/null
+++ b/debian/patches/CVE-2010-2487-XSS.patch
@@ -0,0 +1,221 @@
+Description: XSS by unescaped content emitted by theme.add_msg
+ Backport of upstream VCS (branch 1.7)
+Bug: http://bugs.debian.org/584809
+Bug-Vendor: http://moinmo.in/MoinMoinBugs/1.9.2UnescapedInputForThemeAddMsg
+Origin: upstream, http://hg.moinmo.in/moin/1.7/rev/37306fba2189
+Author: Eugene Syromyatnikov <evgsyr AT gmail.com>
+Last-update: 2010-06-04
+--- a/MoinMoin/Page.py	2008-05-19 09:40:47.000000000 +0200
++++ b/MoinMoin/Page.py	2010-06-07 06:41:50.000000000 +0200
+@@ -1053,8 +1053,8 @@
+                 if 'highlight' in request.form:
+                     del request.form['highlight']
+                 request.theme.add_msg(_('Invalid highlighting regular expression "%(regex)s": %(error)s') % {
+-                                          'regex': self.hilite_re,
+-                                          'error': str(err),
++                                          'regex': wikiutil.escape(self.hilite_re),
++                                          'error': wikiutil.escape(str(err)),
+                                       }, "warning")
+                 self.hilite_re = None
+ 
+@@ -1111,7 +1111,7 @@
+                     request.theme.add_msg("<strong>%s</strong><br>" % (
+                         _('Revision %(rev)d as of %(date)s') % {
+                             'rev': self.rev,
+-                            'date': self.mtime_printable(request)
++                            'date': wikiutil.escape(self.mtime_printable(request))
+                         }), "info")
+ 
+                 # This redirect message is very annoying.
+--- a/MoinMoin/PageEditor.py	2008-06-20 22:10:19.000000000 +0200
++++ b/MoinMoin/PageEditor.py	2010-06-07 06:41:50.000000000 +0200
+@@ -278,14 +278,15 @@
+         elif 'template' in form:
+             # If the page does not exist, we try to get the content from the template parameter.
+             template_page = wikiutil.unquoteWikiname(form['template'][0])
++            template_page_escaped = wikiutil.escape(template_page)
+             if request.user.may.read(template_page):
+                 raw_body = Page(request, template_page).get_raw_body()
+                 if raw_body:
+-                    request.theme.add_msg(_("[Content of new page loaded from %s]") % (template_page, ), 'info')
++                    request.theme.add_msg(_("[Content of new page loaded from %s]") % (template_page_escaped, ), 'info')
+                 else:
+-                    request.theme.add_msg(_("[Template %s not found]") % (template_page, ), 'warning')
++                    request.theme.add_msg(_("[Template %s not found]") % (template_page_escaped, ), 'warning')
+             else:
+-                request.theme.add_msg(_("[You may not read %s]") % (template_page, ), 'error')
++                request.theme.add_msg(_("[You may not read %s]") % (template_page_escaped, ), 'error')
+ 
+         # Make backup on previews - but not for new empty pages
+         if not use_draft and preview and raw_body:
+--- a/MoinMoin/PageGraphicalEditor.py	2008-05-20 20:21:16.000000000 +0200
++++ b/MoinMoin/PageGraphicalEditor.py	2010-06-07 06:41:50.000000000 +0200
+@@ -169,14 +169,15 @@
+         elif 'template' in form:
+             # If the page does not exist, we try to get the content from the template parameter.
+             template_page = wikiutil.unquoteWikiname(form['template'][0])
++            template_page_escaped = wikiutil.escape(template_page)
+             if request.user.may.read(template_page):
+                 raw_body = Page(request, template_page).get_raw_body()
+                 if raw_body:
+-                    request.write(_("[Content of new page loaded from %s]") % (template_page, ), '<br>')
++                    request.write(_("[Content of new page loaded from %s]") % (template_page_escaped, ), '<br>')
+                 else:
+-                    request.write(_("[Template %s not found]") % (template_page, ), '<br>')
++                    request.write(_("[Template %s not found]") % (template_page_escaped, ), '<br>')
+             else:
+-                request.write(_("[You may not read %s]") % (template_page, ), '<br>')
++                request.write(_("[You may not read %s]") % (template_page_escaped, ), '<br>')
+ 
+         # Make backup on previews - but not for new empty pages
+         if not use_draft and preview and raw_body:
+--- a/MoinMoin/action/CopyPage.py	2010-06-07 06:41:49.000000000 +0200
++++ b/MoinMoin/action/CopyPage.py	2010-06-07 06:41:50.000000000 +0200
+@@ -81,7 +81,7 @@
+     def get_form_html(self, buttons_html):
+         _ = self._
+         if self.users_subpages:
+-            subpages = ' '.join(self.users_subpages)
++            subpages = ' '.join([wikiutil.escape(page) for page in self.users_subpages])
+ 
+             d = {
+                 'subpage': subpages,
+--- a/MoinMoin/action/LikePages.py	2008-03-16 20:29:48.000000000 +0100
++++ b/MoinMoin/action/LikePages.py	2010-06-07 06:41:50.000000000 +0200
+@@ -24,19 +24,19 @@
+ 
+     # Error?
+     if isinstance(matches, (str, unicode)):
+-        request.theme.add_msg(matches, "info")
++        request.theme.add_msg(wikiutil.escape(matches), "info")
+         Page(request, pagename).send_page()
+         return
+ 
+     # No matches
+     if not matches:
+-        request.theme.add_msg(_('No pages like "%s"!') % (pagename, ), "error")
++        request.theme.add_msg(_('No pages like "%s"!') % (wikiutil.escape(pagename), ), "error")
+         Page(request, pagename).send_page()
+         return
+ 
+     # One match - display it
+     if len(matches) == 1:
+-        request.theme.add_msg(_('Exactly one page like "%s" found, redirecting to page.') % (pagename, ), "info")
++        request.theme.add_msg(_('Exactly one page like "%s" found, redirecting to page.') % (wikiutil.escape(pagename), ), "info")
+         Page(request, matches.keys()[0]).send_page()
+         return
+ 
+--- a/MoinMoin/action/Load.py	2010-06-07 06:41:49.000000000 +0200
++++ b/MoinMoin/action/Load.py	2010-06-07 06:41:50.000000000 +0200
+@@ -102,7 +102,7 @@
+     'upload_label_file': _('File to load page content from'),
+     'upload_label_comment': _('Comment'),
+     'upload_label_rename': _('Page Name'),
+-    'pagename': self.pagename,
++    'pagename': wikiutil.escape(self.pagename, quote=1),
+     'buttons_html': buttons_html,
+     'action_name': self.form_trigger,
+ }
+--- a/MoinMoin/action/RenamePage.py	2010-06-07 06:41:49.000000000 +0200
++++ b/MoinMoin/action/RenamePage.py	2010-06-07 06:41:50.000000000 +0200
+@@ -80,7 +80,7 @@
+     def get_form_html(self, buttons_html):
+         _ = self._
+         if self.subpages:
+-            subpages = ' '.join(self.subpages)
++            subpages = ' '.join([wikiutil.escape(page) for page in self.subpages])
+ 
+             d = {
+                 'subpage': subpages,
+--- a/MoinMoin/action/backup.py	2008-04-26 20:54:34.000000000 +0200
++++ b/MoinMoin/action/backup.py	2010-06-07 06:41:50.000000000 +0200
+@@ -114,7 +114,11 @@
+     request.theme.send_footer(pagename)
+     request.theme.send_closing_html()
+ 
++# NOTE: consider using ActionBase.render_msg instead of this function.
+ def sendMsg(request, pagename, msg, msgtype):
++    """
++    @param msg: Message to show. Should be escaped.
++    """
+     from MoinMoin import Page
+     request.theme.add_msg(msg, msgtype)
+     return Page.Page(request, pagename).send_page()
+@@ -140,4 +144,4 @@
+         sendBackupForm(request, pagename)
+     else:
+         return sendMsg(request, pagename,
+-                       msg=_('Unknown backup subaction: %s.') % dowhat, msgtype="error")
++                       msg=_('Unknown backup subaction: %s.') % wikiutil.escape(dowhat), msgtype="error")
+--- a/MoinMoin/action/chart.py	2008-02-19 22:26:38.000000000 +0100
++++ b/MoinMoin/action/chart.py	2010-06-07 06:41:50.000000000 +0200
+@@ -6,6 +6,7 @@
+                 2006 MoinMoin:ThomasWaldmann
+     @license: GNU GPL, see COPYING for details.
+ """
++from MoinMoin import wikiutil
+ from MoinMoin.util import pysupport
+ 
+ def execute(pagename, request):
+@@ -27,7 +28,7 @@
+     try:
+         func = pysupport.importName("MoinMoin.stats.%s" % chart_type, 'draw')
+     except (ImportError, AttributeError):
+-        request.theme.add_msg(_('Bad chart type "%s"!') % chart_type, "error")
++        request.theme.add_msg(_('Bad chart type "%s"!') % wikiutil.escape(chart_type), "error")
+         return request.page.send_page()
+ 
+     func(pagename, request)
+--- a/MoinMoin/action/login.py	2008-03-03 00:20:39.000000000 +0100
++++ b/MoinMoin/action/login.py	2010-06-07 06:41:50.000000000 +0200
+@@ -68,7 +68,7 @@
+             if hasattr(request, '_login_messages'):
+                 for msg in request._login_messages:
+                     error.append('<p>')
+-                    error.append(msg)
++                    error.append(wikiutil.escape(msg))
+                 error = ''.join(error)
+             request.theme.add_msg(error, "error")
+             return self.page.send_page()
+--- a/MoinMoin/action/newaccount.py	2010-06-07 06:41:50.000000000 +0200
++++ b/MoinMoin/action/newaccount.py	2010-06-07 06:41:50.000000000 +0200
+@@ -61,7 +61,7 @@
+     if pw_checker:
+         pw_error = pw_checker(theuser.name, password)
+         if pw_error:
+-            return _("Password not acceptable: %s") % pw_error
++            return _("Password not acceptable: %s") % wikiutil.escape(pw_error)
+ 
+     # Encode password
+     if password and not password.startswith('{SHA}'):
+@@ -69,7 +69,7 @@
+             theuser.enc_password = user.encodePassword(password)
+         except UnicodeError, err:
+             # Should never happen
+-            return "Can't encode password: %s" % str(err)
++            return "Can't encode password: %s" % wikiutil.escape(str(err))
+ 
+     # try to get the email, for new users it is required
+     email = wikiutil.clean_input(form.get('email', [''])[0])
+--- a/MoinMoin/action/recoverpass.py	2008-06-12 21:01:24.000000000 +0200
++++ b/MoinMoin/action/recoverpass.py	2010-06-07 06:41:50.000000000 +0200
+@@ -175,7 +175,7 @@
+             if pw_checker:
+                 pw_error = pw_checker(name, newpass)
+                 if pw_error:
+-                    msg = _("Password not acceptable: %s") % pw_error
++                    msg = _("Password not acceptable: %s") % wikiutil.escape(pw_error)
+             if not pw_error:
+                 u = user.User(request, user.getUserId(request, name))
+                 if u and u.valid and u.apply_recovery_token(token, newpass):
+--- a/MoinMoin/action/userprofile.py	2010-06-07 06:41:50.000000000 +0200
++++ b/MoinMoin/action/userprofile.py	2010-06-07 06:41:50.000000000 +0200
+@@ -28,7 +28,7 @@
+         oldval = getattr(theuser, key)
+         setattr(theuser, key, val)
+         theuser.save()
+-        request.theme.add_msg('%s.%s: %s -> %s' % (user_name, key, oldval, val), "info")
++        request.theme.add_msg('%s.%s: %s -> %s' % tuple([wikiutil.escape(s) for s in [user_name, key, oldval, val]]), "info")
+ 
+     Page(request, pagename).send_page()
+ 

Reply via email to